首页 > 解决方案 > 使用 React Router 保护 React 应用程序中的路由

问题描述

我用 , 创建了一个简单的应用React程序Redux,它处理用户身份验证。React RouterAuth0

我正在尝试创建这种基本行为来控制访问:

一切都“几乎”按应有的方式工作。我遇到的问题是render()函数 inApp.jsxlock.on('authenticated')侦听器甚至有机会处理Auth0. 结果,令牌永远不会被存储,并且用户似乎总是未经身份验证。如果我将用户发送到/login,一切正常,因为我没有在呈现Login组件之前检查用户是否经过身份验证。

我认为我处理受保护路由的方式需要改变。关于如何处理受保护的路线有什么建议吗?

我在这里提供您需要的代码。如果您想查看整个应用程序,请转到https://github.com/imsam67/react-redux-react-router-auth0-lock

以下是App.jsx

class App extends Component {

    render() {

        const isAuthed = isAuthenticated();

        return (
            <div>
                <Switch>
                    <Route exact path="/" render={ props => isAuthed ? <Home {...props} /> : <Redirect to="/public" /> } />
                    <Route exact path="/login">
                        <Login />
                    </Route>
                    <Route path="/public">
                        <Public />
                    </Route>
                </Switch>
            </div>
        );
    }
}

这是AuthWrapper我处理的组件Auth0

class AuthWrapper extends Component {

    constructor(props) {

        super(props);
        this.onAuthenticated = this.onAuthenticated.bind(this);

        this.lock = new Auth0Lock('my_auth0_client_id', 'my_domain.auth0.com', {
            auth: {
                audience: 'https://my_backend_api_url',
                redirectUrl: 'http://localhost:3000/',
                responseType: 'token id_token',
                sso: false
            }
        });

        this.onAuthenticated();
    }

    onAuthenticated() {
        debugger; // After successful login, I hit this debugger
        this.lock.on('authenticated', (authResult) => {
            debugger; // But I never hit this debugger
            let expiresAt = JSON.stringify((authResult.expiresIn * 1000) + new Date().getTime());
            sessionStorage.setItem('access_token', authResult.accessToken);
            sessionStorage.setItem('id_token', authResult.idToken);
            sessionStorage.setItem('expires_at', expiresAt);

          });
    }

    render() {

        return(
            <AuthContext.Provider value={{ lock: this.lock }}>
                {this.props.children}
            </AuthContext.Provider>
        );
    }

}

index.js以防万一您需要查看它:

import App from './components/App';
import AuthWrapper from './components/auth/AuthWrapper';

// Store
import appStore from './store/app-store';
const store = appStore();

ReactDOM.render(
    <Provider store={store}>
        <BrowserRouter>
            <AuthWrapper>
                <App />
            </AuthWrapper>
        </BrowserRouter>
    </Provider>,
    document.getElementById('root')
);

标签: reactjsreact-router-v4auth0react-router-dom

解决方案


这是我为完成这项工作所做的更改。

  1. 我现在初始化Auth0 Lockindex.js使其成为全局
  2. 我将onAuthenticated()侦听器移动到LoginCallback.jsx成功登录后发送用户的组件。我相信将onAuthenticated()fromApp.jsx移到 toLoginCallback.jsx产生了最大的影响,因为 listener inLoginCallback.jsx执行 before App.jsx
  3. 成功验证后,我还使用this.props.history.push('/');将用户发送到Home组件

有关完整代码,请参阅https://github.com/imsam67/react-redux-react-router-auth0-lock上的 repo


推荐阅读