another noob question. I'm logging in my user to the system using JWT authorization, getting the token and saving it in localstorage
and then sending a post request that saves data (its a big form basically). Problem is, the sever is invalidating the token after a given time (20 minutes or so) and so, some of my post requests are returning 401 status
. How to verify (and if needed, show a login prompt) before sending the post request? I'm using redux-form
to make my forms.
P.S: I know I'm supposed to use action creators and such, but I'm still a newbie, so not very good at those stuff.
here's my authentication:
export function loginUser(creds) { const data = querystring.stringify({_username: creds.username, _password: creds.password}); let config = { method: 'POST', headers: { 'Content-Type':'application/x-www-form-urlencoded' }, body: data }; return dispatch => { // We dispatch requestLogin to kickoff the call to the API dispatch(requestLogin(creds)); return fetch(BASE_URL+'/login_check', config) .then(response => response.json().then(user => ({ user, response })) ).then(({ user, response }) => { if (!response.ok) { // If there was a problem, we want to // dispatch the error condition dispatch(loginError(user.message)); return Promise.reject(user) } else { // If login was successful, set the token in local storage localStorage.setItem('id_token', user.token); let token = localStorage.getItem('id_token') console.log(token); // Dispatch the success action dispatch(receiveLogin(user)); } }).catch(err => console.log("Error: ", err)) } }
and here's the POST
request (I'm getting the values
object from redux-form
)
const token = localStorage.getItem('id_token'); const AuthStr = 'Bearer '.concat(token); let headers ={ headers: { 'Content-Type':'application/json','Authorization' : AuthStr } }; export default (async function showResults(values, dispatch) { axios.post(BASE_URL + '/new', values, headers) .then(function (response) { console.log(values); console.log(response); }) .catch(function (error) { console.log(token); console.log(values) console.log(error.response); }); });
P.P.S: if anyone has any suggestion for improving my code, feel free to comment.
There are two ways to check if Token is expired or not. I will show you the implementations of both ways. – For 1, we check the token expiration every time the Route changes and call App component logout method. – For 2, we dispatch logout event to App component when response status tells us the token is expired.
We must send the access token to the OneLogin OIDC app's introspection endpoint to validate the token. If the token is valid, the introspection endpoint will respond with an HTTP 200 response code. The body of the response will also contain an augmented version of the original JWT token's payload.
JWT expiration can be checked in two ways. First of all you have to install jsonwebtoken package and require it at the top of your file. Thereafter, you can follow the below ways to check JWT expiration before sending any rest requests.
Option 1
var isExpired = false; const token = localStorage.getItem('id_token'); var decodedToken=jwt.decode(token, {complete: true}); var dateNow = new Date(); if(decodedToken.exp < dateNow.getTime()) isExpired = true;
Option 2
const token = localStorage.getItem('id_token'); jwt.verify(token, 'shhhhh', function(err, decoded) { if (err) { /* err = { name: 'TokenExpiredError', message: 'jwt expired', expiredAt: 1408621000 } */ } });
Check the error of that method. If it is the TokenExpiredError then that means the token is expired.
Here is a solution with jwt-decode library by comparing the exp attributes in the JWT token with current time. (JWT token is simply a Base64 encoded string)
Install jwt-decode (npm install jwt-decode --save
)
let token = localStorage.getItem(TOKEN); let decodedToken = jwt_decode(token); console.log("Decoded Token", decodedToken); let currentDate = new Date(); // JWT exp is in seconds if (decodedToken.exp * 1000 < currentDate.getTime()) { console.log("Token expired."); } else { console.log("Valid token"); result = true; }
IMPORTANT: jwt-decode doesn't validate the token, any well formed JWT can be decoded. You should validate the token in your server-side logic by using something like express-jwt, koa-jwt, Owin Bearer JWT, etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With