【发布时间】:2019-11-13 01:42:18
【问题描述】:
我在 Express 中设置了一个登录路由,当使用它时,它将设置我的应用程序的全局状态(使用 Context API),包括用户 ID 和一个由 JSONWebToken 生成的令牌。
为了能够为用户加载待办事项,您需要有一个有效的令牌,当我在执行 API 请求时在标头中发送它时,该令牌有效。使用 Axios 执行此操作时,状态也在更新,但问题是我不知道如何(或最佳方式)转发到受保护的路由。
这是我的 App.js,其中包括我的 Welcome 和 Todo 组件的路由。在Welcome 内部,有一个Login 组件,它更新AppContext 以包含用户ID 和jsonwebtoken。
import React, { useContext } from 'react'
import { BrowserRouter as Router, Route, Redirect } from 'react-router-dom'
import { Switch } from 'react-router'
import TodoApp from './components/TodoApp/TodoApp'
import Welcome from './components/Welcome/Welcome'
import TodoProvider from './components/TodoApp/TodoContext'
import { AppContext } from './AppContext'
export default function App () {
const context = useContext(AppContext)
const PrivateRoute = ({ component: Component, ...rest }) => (
<Route
{...rest}
render={props =>
context.loggedIn ? <Component {...props} /> : <Redirect to="/" />
}
/>
)
return (
<Router>
<Switch>
<Route exact path="/" component={Welcome} />
<TodoProvider>
<PrivateRoute exact path="/todo" component={TodoApp} />
</TodoProvider>
</Switch>
</Router>
)
}
注意它检查的 context.loggedIn 属性,您可以在本文的最后一个代码块中看到它是如何变化的。
这是我的Login 组件,它位于一个简单的Welcome 组件内
import React, { useState, useContext } from 'react'
import { AppContext } from '../../../AppContext'
export default function Login (props) {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const context = useContext(AppContext)
const handleSubmit = async e => {
e.preventDefault()
try {
// Method which logs in using the /api/login route, and returns users ID and token to the global state (context)
await context.handleLogin(email, password)
} catch {
throw Error('Login error')
}
}
return (
<form handleSubmit={handleSubmit}>
<div className="input-wrapper">
<label htmlFor="email" />
<input
type="text"
id="login_email"
placeholder="email"
value={email}
onChange={e => setEmail(e.target.value)}
/>
</div>
<div className="input-wrapper">
<label htmlFor="password" />
<input
type="password"
id="login_password"
placeholder="password"
value={password}
onChange={e => setPassword(e.target.value)}
/>
</div>
<div className="input-wrapper">
<button
type="submit"
onClick={handleSubmit}
>
Log in
</button>
</div>
</form>
)
}
最后,context.handleLogin 方法更新状态以包含用户 ID 和令牌。取自AppContext.js
handleLogin = (email, password) => {
axios
.post('http://localhost:4000/api/login/', {
email,
password
})
.then(response => {
this.setState({
loggedIn: response.httpStatus === 200,
userID: response.data.data.user._id,
token: response.data.data.token
})
})
.catch(err => {
this.setState({
httpStatus: err.response.status,
loginError: 'Incorrect email/password'
})
})
}
我是 React 的新手,因此我们将不胜感激。提前致谢!
【问题讨论】:
标签: reactjs express authentication react-router axios