admin管理员组

文章数量:1318987

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.

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.

Share Improve this question asked Dec 8, 2020 at 5:36 MoonMoon 8902 gold badges11 silver badges26 bronze badges 2
  • 1 It looks like your API throws back an error if the token is not valid, could you not just use that error as an indication you need a new token? – Cory Harper Commented Dec 8, 2020 at 5:40
  • One method would be to have the token expiry timestamp in localStorage along with the token. And when the token is near to expire you can perform necessary operations such as token regeneration, validation etc – Anwer AR Commented Dec 8, 2020 at 6:28
Add a ment  | 

2 Answers 2

Reset to default 4

I agree with the ment 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);
}

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 pare 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

本文标签: javascriptHow to detect jwt token expire on ReactStack Overflow