【问题标题】:How do I check for token expiration and logout user?如何检查令牌过期和注销用户?
【发布时间】:2017-12-12 10:31:49
【问题描述】:

当他/她单击注销按钮时,用户可以自己注销,但如果令牌过期,他/她无法注销,因为在我的应用程序中,令牌用于服务器端和前端。当用户单击注销按钮时,如果令牌有效,则清除来自服务器和浏览器的令牌。当用户没有注销并且他/她的令牌过期但没有在浏览器中被清除时,可能会出现这种情况。为了解决这种情况,我如何在每次用户访问我的应用时检查令牌是否过期,如果令牌过期,请从浏览器中清除令牌?

我在 saga 中尝试过,每次用户刷新页面或切换到另一个页面时,它都会在后台观看。我不认为这是一种有效的方法。我认为中间件会起作用。

function* loadInitialActions() {
  var dateNow = new Date();
  console.log(jwtDecode(token).exp < dateNow.getTime() - jwtDecode(token).iat);
  const token =
    JSON.parse(localStorage.getItem("user")) &&
    JSON.parse(localStorage.getItem("user"))["token"];
  if (
    token &&
    jwtDecode(token).exp < dateNow.getTime() - jwtDecode(token).iat
  ) {
    yield put(LOGOUT_SUCCESS);
  }
}

function* initialize() {
  const watcher = yield fork(loadInitialActions);
  yield take([INITIALIZE_ERROR, INITIALIZE_SUCCESS]);
  yield cancel(watcher);
}

function* rootSaga() {
  console.log("rootSaga");
  yield takeLatest(INITIALIZE, initialize);
}

所以我的问题是如果令牌从中间件过期,我该如何使用令牌过期逻辑和注销用户?

【问题讨论】:

    标签: javascript reactjs redux jwt redux-saga


    【解决方案1】:

    this.serverResponse.expires_in是以秒为单位的过期时间。

    var tokenexpiration: Date = new Date();
    tokenexpiration.setSeconds(new Date().getSeconds() + parseInt(this.serverResponse.expires_in))
    console.log(tokenexpiration);
    

    您可以将其保存到 localStorage:

    localStorage.setItem('expirationdate',tokenexpiration)
    

    通过简单的条件,您可以随时检查令牌是否已过期。

    【讨论】:

      【解决方案2】:

      在我看来,中间件将是最好的选择。

      你可以这样做

      const checkTokenExpirationMiddleware = store => next => action => {
        const token =
          JSON.parse(localStorage.getItem("user")) &&
          JSON.parse(localStorage.getItem("user"))["token"];
        if (jwtDecode(token).exp < Date.now() / 1000) {
          next(action);
          localStorage.clear();
        }
        next(action);
      };
      

      然后你必须把它包裹在applyMiddleware

      【讨论】:

      • 这就是我要找的。它对我有用。非常感谢您的帮助。
      • @Tushant 我应该在哪里使用这个功能,authguard ?
      • 你可以在 store.js 中使用它,该函数应该放在 applyMiddleware() 中
      • "1000" 是毫秒吗?
      • 我正在使用 store.getState(token) 获取令牌,并且我已使用 redux-persist 将其持久化到本地存储中。但是当我调用它时它返回 null
      【解决方案3】:

      您需要使用 HOC 包装 Main 组件。 HOC 将验证令牌,如果确定则允许组件显示。如果令牌无效,则将登录页面重定向到。

      const authChecker = (Component) => {
        return class extends React.Component {
          state = {
            show: false;
          }
      
          componentWillReceiveProps(nextProps) {
            if (nextProps.children !== this.props.children) {
              this.checkAuth();
            }
          }
      
          componentDidMount() {
            this.checkAuth();
          }
      
          checkAuth() {
            Api.checkAuth()
            .then(result => {
              if (result.success) {
                this.setState({ show: true });
              } else {
                // logout since token expired
                API.logout();
              }
            });
          }
      
          render() {
            return this.state.show && <Component {...this.props} />
          }
        }
      }
      
      export default authChecker(Main);
      

      【讨论】:

      • 签入中间件不是更好吗?
      • 签入中间件是另一种选择,也许更好。软件包 redux-oidc 采用了这种方法。
      • 感谢您的善意和帮助。我可以使用中间件,但我的令牌过期逻辑不起作用。我正在检查令牌已过期或未使用此条件if (token &amp;&amp; jwtDecode(token).exp &lt; dateNow.getTime()) { next(action); localStorage.clear(); action.type = "Project/App/SHOW_TOKEN_INVALID_MESSAGE"; },但使用此逻辑虽然我当前正在登录,但我已注销,因为它说我的令牌已过期。你能帮我处理一下使用 jwt-decode 的令牌过期逻辑吗?
      猜你喜欢
      • 2021-07-31
      • 2018-07-30
      • 2020-09-11
      • 2020-02-20
      • 2020-04-16
      • 2022-01-23
      • 1970-01-01
      • 2021-10-05
      • 1970-01-01
      相关资源
      最近更新 更多