javascript React - 如何在发送发布请求之前检查 JWT 是否有效?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/46418975/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 06:39:27  来源:igfitidea点击:

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

javascriptreactjsloginreduxjwt

提问by Samia Ruponti

another noob question. I'm logging in my user to the system using JWT authorization, getting the token and saving it in localstorageand 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-formto make my forms.

另一个菜鸟问题。我正在使用 JWT 授权将我的用户登录到系统,获取令牌并将其保存localstorage,然后发送一个保存数据的发布请求(基本上是一个大表单)。问题是,服务器在给定时间(20 分钟左右)后使令牌无效,因此,我的一些帖子请求正在返回401 status。在发送 post 请求之前如何验证(如果需要,显示登录提示)?我正在使用redux-form我的表格。

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.

PS:我知道我应该使用动作创建器之类的,但我仍然是新手,所以不太擅长这些东西。

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 POSTrequest (I'm getting the valuesobject from redux-form)

这是POST请求(我正在values从获取对象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.

PPS:如果有人对改进我的代码有任何建议,请随时发表评论。

回答by Suvethan Nantha

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.

JWT 过期可以通过两种方式检查。首先,您必须安装 jsonwebtoken 包并将其放在文件的顶部。此后,您可以按照以下方法在发送任何休息请求之前检查 JWT 到期时间。

Option 1

选项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

选项 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.

检查该方法的错误。如果是 TokenExpiredError 则表示令牌已过期。

回答by directory

You could also use a middleWare to check if the token has been expired. You even could update the token if it will almost expire. For example, you could do something shown below;

您还可以使用中间件来检查令牌是否已过期。如果令牌即将到期,您甚至可以更新它。例如,您可以执行如下所示的操作;

 export function jwtMiddleware({ dispatch, getState }) {
  return (next) => (action) => {
    switch (action.type) {
      case 'CHECK_AUTH_TOKEN' :
        if (getState().auth && getState().auth.token) {
          var tokenExpiration = jwtDecode(getState().auth.token).exp;
          var tokenExpirationTimeInSeconds = (tokenExpiration - moment(Math.floor(Date.now() / 1000)));
          if (tokenExpiration && tokenExpirationTimeInSeconds < 20) {
            history.push(i18next.t('translation:routes.auth.logout'));
          }
        }
      break;
      case 'UPDATE_AUTH_TOKEN' :
        if (getState().auth && getState().auth.token) {
          var tokenExpiration = jwtDecode(getState().auth.token).exp;
          var tokenExpirationTimeInSeconds = (tokenExpiration - moment(Math.floor(Date.now() / 1000)));
          if (tokenExpiration && tokenExpirationTimeInSeconds < 100 && tokenExpirationTimeInSeconds > 20) {
            if (!getState().auth.fetching) {
              return dispatch(refreshAuthToken(getState().auth));
            }
          }
        }
      break;
      case 'REFRESH_AUTH_TOKEN_FAIL' :
        if (getState().auth && getState().auth.token) {
          return dispatch(removeAuthToken(getState().auth)).then(response => {
            history.push(i18next.t('translation:routes.auth.logout'));
          });
        }
      break;
      }
    return next(action);
  }
}