使用 React Router PrivateRoute 处理 Refreshtoken

Handling Refreshtoken with React Router PrivateRoute

我正在使用 React-Router V4,我想提交一个 'authenticated' 道具来决定是将用户发送到登录页面还是请求的页面:

PrivateRoute.js

import React from "react";
import {
  Route,
  Redirect,
} from "react-router-dom";
const PrivateRoute = ({ component: Component, authenticated, ...rest }) => (
    <Route
      {...rest}
      render={props =>
        authenticated ? (
          <Component {...props} />
        ) : (
          <Redirect
            to={{
              pathname: "/login",
              state: { from: props.location }
            }}
          />
        )
      }
    />
)
export default PrivateRoute;

我的 App.js 看起来像这样:

class App extends Component {

is_authenticated() {
    const token = localStorage.getItem('access_token');
    //if token is not expired send on the way
    if (token && jwt_decode(token).exp > Date.now() / 1000) {
      return true;
    } else {
    // if token is expired try to refresh
    const refresh_token = localStorage.getItem('refresh_token');
    if(refresh_token) {
      axios.post(config.refresh_url,{},{
                  headers: {"Authorization": `Bearer ${refresh_token}`},
                  "crossdomain": true,
                  mode: 'no-cors',}).then(
                    response => {
                      const access_token = response.data.access_token;
                      localStorage.setItem('access_token', access_token)
                      return access_token ? true : false
                    }
                  )
      }
    }
    return false
  }

  render() {
    const client = this.client;
    return (
      <Router>
        <div>
          <Route exact path="/login" component={Login} />
          <PrivateRoute exact path="/" component={Home} authenticated={this.is_authenticated()} />
        </div>
      </Router>
    );
  }
}

export default App;

由于 Axios 调用是异步的,因此组件会在调用完成之前呈现。

如何让渲染器等待令牌刷新?

我会在 App 组件状态中保留 isAuthenticated。然后,您可以在 isAuthenticated 调用中使用 setState 来重新呈现结果。当令牌过期时,这也很重要。