Moon
Moon

Reputation: 890

How to detect jwt token expire on React

With the backend node.js, I have created a JWT token with a expire time:

signToken = (user) => {
    return jwt.sign({ id: user.userId }, process.env.JWT_SECRET, { expiresIn: 60 * 60 * 24 * 10 }) // 1h = 60 * 60
}

With the fronend React app, when the user login, I will pass this JWT token with the return data and save it to localstorage(I'm using Redux):

const result = await userLogin({ username, password })
dispatch({ type: USER_LOGIN_SUCCESS, payload: result.data.data })
const { userReducer } = getState()
window.localStorage.setItem("accessToken", JSON.stringify(userReducer.token))

Each api required this token for authorization, I will pass this in the header. I set it in the axios request interceptors:

instance.interceptors.request.use(
    (config) => {
        const accessToken = localStorage.getItem("accessToken")
        config.headers.Authorization = accessToken ? `Bearer ${accessToken}` : ""
        if (config.url.includes("/files/")) {
            config.headers["Content-Type"] = "multipart/form-data"
        }
        return config
    },
    (error) => {
        return Promise.reject(error.response)
    }
)

My question is how can I detect if the token is expire or not on React. With this React app, I'm using axios, redux, react-redux and react router.

Upvotes: 0

Views: 15275

Answers (2)

Ntshembo Hlongwane
Ntshembo Hlongwane

Reputation: 1051

Okay to add on to the answer that was given is, lets say you set jwt token that last 10days from now you would do something like this: 10 * 24 * 60 * 60 * 1000 so this will set 10 day from now in milliseconds.

Now when you receive the token in server that expiration in milliseconds is there now what you do is, do not wait get the error message but what you do is compare if the date in token(in milliseconds) is greater than the current date then if that holds to be true then you know the token is still valid...

Alternative

Since you are already storing Jwt in localStorage you can swich to storing in Cookie really does not make a difference but would be helpful in the sense that once token expires it will be removed from your cookie storage making server validation easy i.e if cookie not sent it means it has expired but this is only applicable when storing in cookies

Upvotes: 1

Abir Taheer
Abir Taheer

Reputation: 2783

I agree with the comment made by Cory which is that you should instead do validation on the server instead of the client. If you want to do some basic checks, the following will work assuming your JWT body is not encrypted.

// Some fake JWT I made using an online builder
const exampleJWT = `eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE2MDc0MDc3NTYsImV4cCI6MTYzODk0Mzc1NiwiYXVkIjoid3d3LmV4YW1wbGUuY29tIiwic3ViIjoianJvY2tldEBleGFtcGxlLmNvbSIsIkdpdmVuTmFtZSI6IkpvaG5ueSIsIlN1cm5hbWUiOiJSb2NrZXQiLCJFbWFpbCI6Impyb2NrZXRAZXhhbXBsZS5jb20iLCJSb2xlIjpbIk1hbmFnZXIiLCJQcm9qZWN0IEFkbWluaXN0cmF0b3IiXX0.cfBNHOIaUSAVtLHbxlOmMZtp-giA7-v8yJpMyGooefE`;

function getPayload(jwt){
  // A JWT has 3 parts separated by '.'
  // The middle part is a base64 encoded JSON
  // decode the base64 
  return atob(jwt.split(".")[1])
}

const payload = getPayload(exampleJWT);

const expiration = new Date(payload.exp);
const now = new Date();
const fiveMinutes = 1000 * 60 * 5;

if( expiration.getTime() - now.getTime() < fiveMinutes ){
  console.log("JWT has expired or will expire soon");
} else {
  console.log("JWT is valid for more than 5 minutes", payload);
}

Upvotes: 4

Related Questions