【发布时间】:2020-07-03 20:23:00
【问题描述】:
我目前正在开发一个应用程序,使用带有 Passport.js 的 MERN 堆栈进行身份验证,特别是 Google OAuth2 策略。我当前的应用程序具有简单的登录功能,可以从客户端重定向到 Google 同意页面并返回到服务器的重定向 url,然后应该重定向到客户端的主应用程序。我很确定这就是你在服务器端需要做的所有事情,现在我对如何在 React Router 端处理这个有点困惑。
首先,我的公共路由中有我的 Google 登录按钮,然后点击触发 Google OAuth 的服务器中的端点
class Public extends Component {
render() {
return (
<div>
<h1>Public Route</h1>
<a href="http://localhost:5000/api/auth/google">Sign In</a>
</div>
)
}
}
服务器从 localhost:5000/auth/google/redirect 重定向到 localhost:3000/protected 之后>,我相信它可以追溯到触发 React 路由器的 App.js
class App extends Component {
constructor(props) {
super(props)
this.state = { authenticated: false }
}
componentDidMount() {
api.get('/auth/user').then(({data}) => {
if (data) this.setState({authenticated: true})
}).catch((err) => console.error(err))
}
render() {
const { authenticated } = this.state
return (
<div className="App">
<Switch>
<Route exact path='/' component={Public} />
<PrivateRoute exact authed={authenticated} path='/app' component={Protected} />
</Switch>
</div>
)
}
}
这就是事情变得有点混乱的地方。所以我认为它会在 componentDidMount() 之前先渲染,所以 authenticated 状态仍然是 false 所以 PrivateRoute 将客户端重定向回 localhost:3000/ 并呈现公共路线。然后,运行 componentDidMount() 并最终获取用户,现在 authenticated 为真,但现在为时已晚,因为客户端已经重定向到 localhost:3000/ 所以它不再访问 PrivateRoute。
如果有人想知道,这是我的 PrivateRoute 组件:
const PrivateRoute = ({ component: Component, authed, ...rest }) => (
<Route { ...rest} render={(props) => authed ?
<Component {...props} /> :
<Redirect to={{pathname: '/'}} />
} />
)
到目前为止我做了什么:
- 使用 componentWillMount() - 没有区别,而且我相信这很快就会被弃用
- 使用具有 isAuthenticated、login() 和 logout() 成员的全局身份验证对象。我在我的公共组件中创建了该对象的一个实例,并添加了 onClick={auth.login} 以及 href。但是,onClick 在 href 浏览器重定向之前首先运行,因此它会首先尝试获取用户(即使还没有任何设置),因此 isAuthenticated 不会设置为 true
提前致谢!
【问题讨论】:
-
我遇到了类似的问题。在 Google 成功验证身份后,您是否设法在 React 上设置
isAuthenticated:true?
标签: reactjs authentication react-router passport-google-oauth