Я настроил маршрут входа в Express, который при его использовании устанавливает глобальное состояние моего приложения (с использованием Context API), включая идентификатор пользователя и токен, сгенерированный JSONWebToken.
Чтобы иметь возможность загружать элементы задач для пользователя, вам необходимо иметь действительный токен, который работает, когда я отправляю его в заголовки при выполнении запроса API. Состояние также обновляется при выполнении этого с Axios, но проблема в том, что я не знаю, как (или лучший способ как) переадресовать на защищенный маршрут.
Вот мой App.js, который включает в себя маршруты для моих Welcome
и Todo
компонентов. Внутри Welcome
есть компонент Login
, который обновляет AppContext, чтобы содержать идентификатор пользователя и 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
, который обновляет состояние, чтобы содержать идентификатор пользователя и токен. Взято из 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, поэтому любая помощь будет принята с благодарностью. Заранее спасибо!