obabichev / react-token-auth

84 stars 22 forks source link

Token is not refreshed #24

Closed ICS-Vortex closed 2 years ago

ICS-Vortex commented 2 years ago

Hello guys. Any ideas why access token is not refreshing? I am using code straightly from readme. When I set TTL for my token 2seconds - after refreshing page - my authFetch fails with message 'authFetch' was called without access token. Probably storage has no session or session were expired but token is still inside localStorage.

import {createAuthProvider} from 'react-token-auth';
import history from "../history";
import {PAGE_LOGIN} from "../constants/routes";

export type Session = { token: string; refreshToken: string };

export const {useAuth, authFetch, login, logout} =
    createAuthProvider<Session>({
        getAccessToken: storage => storage.token,
        onUpdateToken: async (token) => {
            return fetch(process.env.REACT_APP_API_HOST + '/api/token/refresh', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({refreshToken: token.refreshToken})
            }).then(r => r.json());
        }
    });

as an example - my basic redux action to fetch user from API

import {UserAction, UserActionTypes} from "../types/user";
import {Dispatch} from "redux";
import i18n from "../../i18n";
import {authFetch, useAuth, logout} from "../../providers/authProvider";

export const fetchUser = () => {
    return (dispatch: Dispatch<UserAction>) => {
        dispatch({type: UserActionTypes.FETCH_USER});

        try {
            authFetch(process.env.REACT_APP_API_HOST + `/api/${i18n.language}/profile/`)
                .then( r => r.json())
                .then(response => {
                    dispatch({type: UserActionTypes.FETCH_USER_SUCCESS, payload: response.data.user});
                })
                .catch(e => {
                    dispatch({
                        type: UserActionTypes.FETCH_USER_ERROR,
                        payload: i18n.t('message.fetch_user_error')
                    })
                })
            ;

        } catch (e) {
            console.log(e);
            alert('Error');
            dispatch({
                type: UserActionTypes.FETCH_USER_ERROR,
                payload: i18n.t('message.fetch_user_error')
            })
        }
    };
};

I call this method in Navbar component when user is logged


const NavbarComponent: React.FC = () => {
    const {user} = useTypedSelector(state => state.user);
    const dispatch = useDispatch();
    const [isLogged] = useAuth();

    const handleLogout = () => {
        logout();
        localStorage.removeItem('ucid');
        history.push(PAGE_LOGIN);
    };
    const handleProfile = () => {
        history.push(PAGE_PROFILE);
    };

    useEffect(() => {
        console.log('Logged:', isLogged);
        console.log('User:', user);
    }, []);

    useEffect(() => {
        if (isLogged) {
            dispatch(fetchUser());
        }
    }, [isLogged]);
obabichev commented 2 years ago

Hi, thank you for the feedback, I will try to reproduce it and fix

If you have repo I can reproduce it faster I will be happy to use it, it may speedup me

obabichev commented 2 years ago

Thank you one more time,

fixed in version 2.3.8

The problem was in the usage of Buffer which is available only in node (by default). Now it's replaced with simple implementation without the usage of Buffer/atob.