I was learning how to create a login system using JWT tokens. And as we know, this strategy involves creating two tokens: access_token
and refresh_token
.
Regarding the refresh_token
, it is saved in a cookie and is managed server-side. The access_token
is managed by the user (front-end application), where most tutorials on the internet save it in localStorage
.
After some research, I came to the conclusion that the best alternative is to save this token (access_token
) within the application’s memory.
To try to achieve the same result, I created a context called AuthContext.js
:
import { useState, createContext, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import axios from 'axios';
export const AuthContext = createContext({});
const AuthProvider = ({ children }) => {
const [accessToken, setAccessToken] = useState(null);
const signIn = async (email, password) => {
setLoadingAuth(true);
try {
const { data } = await axios.post('http://localhost/signIn', { email: email, password: password });
setAccessToken(data.accessToken);
setLoadingAuth(false);
navigate('/dashboard');
} catch (error) {
alert(error.response.data.message);
setLoadingAuth(false);
console.error(error);
}
}
return(
<AuthContext.Provider value={{ accessToken, userInfo, loadingAuth, loading, signIn, logout }}>
{children}
</AuthContext.Provider>
);
}
export default AuthProvider;
Which is being imported into App.js
together with the React Router DOM library:
export default function App() {
return (
<BrowserRouter>
<AuthProvider>
<RouterApp />
</AuthProvider>
</BrowserRouter>
);
}
The problem is that after the user refreshes the browser screen, the access_token
that was stored within the accessToken
state is LOST.
Obviously because it is being saved in memory. However, as my application didn’t close, I believe the accessToken
should still store that value, right?
To get around this problem, I’m thinking about creating a SINGLETON
, that is, a class that will use the object.freeze
function in order to persist the accessToken
for some time.
Would this be the best alternative?
2
Answers
You can use local storage
To store the access token in the application memory, you could create a class for managing it, such as:
authenticationManager.js
And then after a successful login, you can set the access token. Something similar to:
authenticationService.js
If you have a class that performs API requests, you can check if the access token has been set before performing a request. If it hasn’t, you can use the refresh token to obtain a new access token before executing the original request. Something similar to:
apiClient.js
As long as your refresh token cookie has been set to persist between browser sessions, it can be used to refresh the access token every time a new session is created (or the browser is refreshed).
If the access token stored in the application memory has expired, it will be refreshed when it’s used to make an API request.