Các bác handle kiểm tra đăng nhập trong Vue, React thế nào

Trong vue, react, spa nói chung. Khi giao tiếp với rest service, giả sử chức năng người dùng đang thực hiện yêu cầu đăng nhập, lúc này người dùng ở 1 tab khác nhấn đăng xuất hoặc token hết hạn… lúc đó nếu thực hiện request đó thì ở server sẽ yêu cầu đăng nhập lại.
Đến đây thì hướng giải quyết có vẽ đơn giản: thêm chức năng kiểm tra, nếu response trả về báo là chưa đăng nhập thì redirect đến trang đăng nhập.
Nhưng nếu có cả trăm method như vậy thì chả lẽ với mỗi phương thức như vầy đều phải wrap cái hàm kiểm tra này vào sao:
Ví dụ nhé:

function createPost() {  ...... if(response.result == notLogged) redirectToLoginComponent() ... }
function deletePost() {  ...... if(response.result == notLogged) redirectToLoginComponent()  ... }
function addComment() {  ...... if(response.result == notLogged) redirectToLoginComponent()  ... }
...

Không biết trong những trường hợp này các bác xử lý sao nhỉ.

Cuối cùng thì các hàm này sẽ phải dùng tới chức năng gọi API (ajax, fetch, axios…).
Bạn chỉ cần check response ở hàm gọi API đó thôi.

1 Like

Theo mình thì ở phần sắp xếp router ngoài cùng ta sẽ đặt luôn dòng check login, sau đó mới tiến hành render app(thực hiện redirect tùy vào trường hợp)

Nhược điểm là hàm này luôn luôn bị check sau mỗi lần render, tuy nhiên code sẽ ngắn.
Nếu người dùng login ở tab khác thì ta thay đổi từ cookie trình duyệt, lúc này giao tiếp phía client chỉ cần kiểm tra cookie, login hay loogut đã có server xử lí, và nó chỉ tốn 1 request mỗi lượt

2 Likes

Bên React có khái niệm High Order Component (HOC) để kiểm tra khi chuyển 1 route

import React, { Component } from 'react';
import { connect } from 'react-redux';

export default function(ComposedComponent) {
  class Authentication extends Component {
    static contextTypes = {
      router: React.PropTypes.object
    }

    componentWillMount() {
      if (!this.props.authenticated) {
        this.context.router.push('/');
      }
    }

    componentWillUpdate(nextProps) {
      if (!nextProps.authenticated) {
        this.context.router.push('/');
      }
    }

    render() {
      return <ComposedComponent {...this.props} />;
    }
  }

  function mapStateToProps(state) {
    return { authenticated: state.auth.authenticated };
  }

  return connect(mapStateToProps)(Authentication);
}

Component nào cần kiểm tra thì cho HOC wrap lại.

<Route path="feature" component={RequireAuth(Feature)} />
2 Likes

Thanks mấy bác,
@Tong_Anh_Thu: Trong Vuejs hình như ít dùng HOC nhưng cách của bạn ở trên có thể dùng Navigation Guard để thực hiện tương tự.

Mình không biết VueJS nên không biết cách kiểm tra Authentication. Tuy nhiên, không có giải pháp nào chung giữa Vue, React, Angular hay VanillaJS.
Bên React dùng HOC, AngularJS 1.0 có interceptor. Mình không rõ Vue nên làm phần nào.

Nếu có điểm chung thì mình nghĩ giải quyết authentication bằng cách sử dụng core, không phụ thuộc vào thư viện ngoài.

1 Like

VueJS nếu code bằng nuxtjs framework thì có khái niệm middleware tương tự như trên server, còn ko thì chỉ có thể sử dụng navigation guards như bạn nói /
Mà tốt nhất là nên sử dụng check login ở trên server api thôi cần gì loàng ngoằng

Ý thớt là đang dính phải trường hợp user bật 2 tab, logged in ở 1 tab, giờ quay sang tab kia thì redirect như thế nào ấy bạn :grinning:

Vậy thì như này là đủ

axios.interceptors.response.use((response) => {
    return response;
}, function (error) {
    // Do something with response error
    if (error.response.status === 401) {
        console.log('unauthorized, logging out ...');
        auth.logout();
        router.replace('/auth/login');
    }
    return Promise.reject(error.response);
});

google , facebook logout 1 tab thì tab kia click vào btn nào cũng redirect hết, chắc redirect là ổn

4 Likes

Có thể dùng cách này:

axios.interceptors.request.use(function (config) {
    const token = this.$store.state.user.token;
    if (token) {
        config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
}, function (err) {
    if (err.response.status === 401) {
        
        console.log('*********************************');
        console.log('unauthorized, logging out ...');
        console.log('*********************************');

        // auth.logout();
        // router.replace('/auth/login');
    }
    return Promise.reject(err.response);
});

Mình biết đây là post đã lâu. Sử dụng interceptor axios.interceptors.request.use trong axios cũng là cách là mình dùng giống @Sirus_Johan

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?