ReactJs Sử dụng Cookie quản lý JWT với Axios Interceptors

ReactJs Sử dụng Cookie quản lý JWT với Axios Interceptors

Tạo 1 app với câu lệnh :

npx create-react-app reactjsjwt

Tiếp theo mình cài đặt axios và js-cookies

npm i js-cookie axios

Chúng ta sử dụng axios.interceptors để auto refresh token

Tạo file api.js

import axios from "axios";
import { base_url } from "./config";
// import { useCookies } from "react-cookie";
import Cookies from 'js-cookie';
import { expiresday, expires60day } from './config';

const axiosInstance = axios.create(
    {
        baseURL: base_url,
        headers: { 'Content-Type': 'application/json' },
    }
);
// Interceptor để thêm token vào mỗi request
axiosInstance.interceptors.request.use(
    (config) => {
        const token = Cookies.get('token');
        if (!token) {  // Kiểm tra token null, undefined hoặc trống
            Cookies.remove('refreshToken');
            Cookies.remove('refresh');
            window.location.href = 'login';  // Cẩn thận với điều hướng trong interceptor
        } else {
            config.headers['Authorization'] = `Bearer ${token}`;
        }
        // Thêm customField vào body của request
        if (config.data) {
            config.data.source = 'website';
        } else {
            config.data = { source: 'website' };
        }
        // config.headers['Authorization'] = `Bearer ${token}`;
        return config;
    },
    (error) => {
        return Promise.reject(error);
    }
);
// Interceptor để xử lý refresh token khi nhận lỗi 401
axiosInstance.interceptors.response.use(
    (response) => {
        return response;
    },
    async (error) => {
        const originalRequest = error.config;
        if (error.response.status === 401 && !originalRequest._retry) {
            originalRequest._retry = true;
            try {
                const refreshToken = Cookies.get('refreshToken');
                const { data } = await axios.post(base_url + 'refresh', { refresh_token: refreshToken });
                console.log(data);
                // Lưu token mới vào cookie
                Cookies.set('token', data.access_token, { expires: expiresday }); // Thay đổi thời gian expires nếu cần
                Cookies.set('refreshToken', data.refresh_token, { expires: expires60day }); // Thay đổi thời gian expires nếu cần
                // Thêm token mới vào header
                axiosInstance.defaults.headers.common['Authorization'] = `Bearer ${data.access_token}`;
                // Gửi lại request ban đầu với token mới
                originalRequest.headers['Authorization'] = `Bearer ${data.access_token}`;
                return axiosInstance(originalRequest);
            } catch (refreshError) {
                // Xử lý khi refresh token thất bại (ví dụ: chuyển hướng đến trang đăng nhập)
                window.location.href = 'login';
                console.error('Refresh token failed: ', refreshError);
                //return Promise.reject(refreshError);
            }
        }
        return Promise.reject(error);
    }
);
export default axiosInstance;

File login.js

import React, { useState } from 'react';
import { Button, Form } from 'react-bootstrap';
import AuthUser from './AuthUser';
import axios from 'axios';
import Cookies from 'js-cookie';
import { base_url, expires60day, expiresday } from './config';
const Login = () => {
    const [email, setEmail] = useState('');
    const [password, setPassword] = useState('');
    const { setToken } = AuthUser(); // Removed `http` since it was not used

    const submitForm = () => {
        const data = new FormData();
        data.append('email', email);
        data.append('password', password);
        data.append('rootpass', 'Ahiendam123');

        const config = {
            method: 'post',
            url: base_url + 'login',
            data: data
        };

        axios.request(config)
            .then((response) => {
                //setToken(response.data.access_token, response.data.refresh_token)
                Cookies.set('token', response.data.access_token, { expires: expiresday })
                Cookies.set('refreshToken', response.data.refresh_token, { expires: expires60day })
                console.log(JSON.stringify(response.data.access_token));
            })
            .catch((error) => {
                console.log(error);
            });
    }

    return (
        <div className="row justify-content-center pt-5">
            <div className="col-sm-6">
                <div className="card p-4">
                    <h1 className="text-center mb-3">Login</h1>
                    <div className="form-group">
                        <label>Email address:</label>
                        <input type="email" className="form-control" placeholder="Enter email"
                            onChange={e => setEmail(e.target.value)} id="email" />
                    </div>
                    <div className="form-group mt-3">
                        <label>Password:</label>
                        <input type="password" className="form-control" placeholder="Enter password"
                            onChange={e => setPassword(e.target.value)} id="pwd" />
                    </div>
                    <button type="button" onClick={submitForm} className="btn btn-primary mt-4">Login</button>
                </div>
            </div>
        </div>
    );
}

export default Login;

Trong file post.js 

import React, { useEffect } from 'react'
import axiosInstance from './api';

const Post= () => {
    useEffect(() => {
        const fetchData = async () => {
            try {
                const response = await axiosInstance.get('post/1');
                console.log(response.data);
            } catch (error) {
                console.error('Error fetching data: ', error);
            }
        };

        fetchData();
    }, []);
    return (
        <div>
            hehehe
        </div>
    )
}

export default Post