【发布时间】:2020-04-26 10:36:51
【问题描述】:
我创建了一个简单的React 应用程序,其中包含处理用户身份验证的Redux、React Router 和Auth0。
我正在尝试创建此基本行为来控制访问:
- 所有未经身份验证的用户将自动发送到
/public - 经过身份验证的用户可以访问应用程序的所有其他部分
- 一旦用户通过
Auth0的身份验证,我想处理access_token并将用户发送到/这是Home组件
一切都“几乎”按应有的方式工作。我遇到的问题是App.jsx 中的render() 函数在lock.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>
);
}
}
这是我处理Auth0 的AuthWrapper 组件:
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')
);
【问题讨论】:
-
我实际上并没有看到你在哪里使用你的减速器中的“isAuthenticated”属性。在 App.jsx 中,您指的是您的 isAuthenticated() 实用程序,但由于这不是反应状态,因此如果它发生变化,它不会触发重新渲染。你需要使用你的 reducer state 属性来保护你的路由,而不是那个 helper util。
-
我在
appReducer中改用isAuthenticated,而不是使用 util 函数,但这不起作用。我读过 Tyler McGinnis 的文章,但问题是我不想在保护区使用/private之类的东西。我希望根目录和它之后的任何东西都受到保护,即/和/projects。唯一不应该保护的路由是/public。所以我无法真正从文章中汲取灵感并将其应用到我的代码中。 -
嘿山姆,对不起,没有工作。也许我只是瞎了眼,但我查看了您的存储库,但没有看到您在用户成功验证后在哪里调用您的操作来更新减速器。如果它在那里,你能指出来吗?
-
抱歉,我没有更新 repo,但现在我更新了。我在
AuthWrapper.jsx下的src/components/auth组件中的onAuthenticated()mehtod 中执行此操作。似乎真正的问题是,在onAuthenticated()方法完全执行并存储access_token之前,会发生到组件的路由。
标签: reactjs react-router-v4 auth0 react-router-dom