Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React - How to check if JWT is valid before sending a post request?

Tags:

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.

like image 616
Samia Ruponti Avatar asked Sep 26 '17 06:09

Samia Ruponti


People also ask

How do you check if JWT token is valid in react?

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.

How JWT token is validated for each request?

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.


2 Answers

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.

like image 183
Suvethan Nantha Avatar answered Sep 28 '22 01:09

Suvethan Nantha


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.

like image 33
Jafar Karuthedath Avatar answered Sep 28 '22 03:09

Jafar Karuthedath