簡體   English   中英

React - 如何在發送發布請求之前檢查 JWT 是否有效?

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

另一個菜鳥問題。 我正在使用 JWT 授權將我的用戶登錄到系統,獲取令牌並將其保存在localstorage ,然后發送一個保存數據的發布請求(它基本上是一個大表單)。 問題是,服務器在給定時間(20 分鍾左右)后使令牌無效,因此,我的一些發布請求返回401 status 在發送 post 請求之前如何驗證(如果需要,顯示登錄提示)? 我正在使用redux-form來制作我的表單。

PS:我知道我應該使用動作創建器之類的,但我仍然是新手,所以不太擅長這些東西。

這是我的身份驗證:

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))
    }
}

這是POST請求(我從redux-form獲取values對象)

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);
    });
});

PPS:如果有人對改進我的代碼有任何建議,請隨時發表評論。

JWT 過期可以通過兩種方式檢查。 首先,您必須安裝 jsonwebtoken 包並將其放在文件頂部。 此后,您可以按照以下方法在發送任何休息請求之前檢查 JWT 到期時間。

選項 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;

選項 2

const token = localStorage.getItem('id_token');
jwt.verify(token, 'shhhhh', function(err, decoded) {
  if (err) {
    /*
      err = {
        name: 'TokenExpiredError',
        message: 'jwt expired',
        expiredAt: 1408621000
      }
    */
  }
});

檢查該方法的錯誤。 如果是 TokenExpiredError 則表示令牌已過期。

這是通過將 JWT 令牌中的 exp 屬性與當前時間進行比較來使用jwt-decode庫的解決方案。 (JWT 令牌只是一個 Base64 編碼的字符串)

  • 安裝 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; }

重要提示: jwt-decode不驗證令牌,任何格式良好的 JWT 都可以解碼。 您應該使用 express-jwt、koa-jwt、Owin Bearer JWT 等來驗證服務器端邏輯中的令牌。

您還可以使用中間件來檢查令牌是否已過期。 如果令牌即將到期,您甚至可以更新它。 例如,您可以執行如下所示的操作;

 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);
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM