0

Here are my custom hooks:

const useRefreshToken = () => {
    const { setAuth } = useAuth();

    const refresh = async () => {
        await axios.get('/refresh', {
            withCredentials: true
        }).then((response) => {
            setAuth((prev: any) => {
                return {
                    ...prev,
                    role: response.data.role,
                    accessToken: response.data.accessToken
                }
            });
            return response.data.accessToken;
        })
    }
    return refresh;
};

const useAccessToken = () => {
    const {auth} = useAuth()
    const refresh = useRefreshToken();
    const token = auth?.accessToken

    return async () => {
        if (token && isExpired(token)) {
            await refresh();
        }
    }
}
const useAxiosPrivate = () => {
    const refresh = useRefreshToken();
    const { auth } = useAuth();

    useEffect(() => {
        const requestIntercept = axiosPrivate.interceptors.request.use(
            config => {
                if (config.headers !== undefined && !config.headers['Authorization']) {
                    config.headers['Authorization'] = `Bearer ${auth?.accessToken}`;
                }
                return config;
            }, (error) => Promise.reject(error)
        );

        const responseIntercept = axiosPrivate.interceptors.response.use(
            response => response,
            async (error) => {
                const prevRequest = error?.config;
                if (error?.response?.status === 403 && !prevRequest?.sent) {
                    prevRequest.sent = true;
                    const newAccessToken = await refresh();
                    prevRequest.headers['Authorization'] = `Bearer ${newAccessToken}`;
                    return axiosPrivate(prevRequest);
                }
                return Promise.reject(error);
            }
        );

        return () => {
            axiosPrivate.interceptors.request.eject(requestIntercept);
            axiosPrivate.interceptors.response.eject(responseIntercept);
        }
    }, [auth, refresh])

    return axiosPrivate;
}

So I want to use useAccessToken() hook to check if the current accessToken in my state is not expired before requesting backend. If it is expired, then I need to use useRefreshToken() to ask backend for new tokens and when the expired token will be replaced with the new one, I wanna send the actual request to backend.

But when I try to use those hooks like this:

const Api() {
    const axiosPrivate = useAxiosPrivate()
    const accessToken = useAccessToken()

    const exampleApiCall = async (data: Data) => {
     
        await accessToken().then(() =>
            axiosPrivate.post(`/api`, data)
        )
      
    }
}

Then the request is sent with the old, expired accessToken. The new one is used when I invoke the request again but it does not satisfy me

0 Answers0