Я пытаюсь защитить свои маршруты в ReactJS. На каждом защищенном маршруте я хочу проверить, хорош ли пользователь, сохраненный в localStorage.
Ниже вы можете увидеть мой файл маршрутов (app.js):
class App extends Component {
render() {
return (
<div>
<Header />
<Switch>
<Route exact path = "/" component = {Home} />
<Route path = "/login" component = {Login} />
<Route path = "/signup" component = {SignUp} />
<Route path = "/contact" component = {Contact} />
<ProtectedRoute exac path = "/user" component = {Profile} />
<ProtectedRoute path = "/user/person" component = {SignUpPerson} />
<Route component = {NotFound} />
</Switch>
<Footer />
</div>
);
}
}
Мой файл protectedRoute:
const ProtectedRoute = ({ component: Component, ...rest }) => (
<Route {...rest} render = {props => (
AuthService.isRightUser() ? (
<Component {...props} />
) : (
<Redirect to = {{
pathname: '/login',
state: { from: props.location }
}}/>
)
)} />
);
export default ProtectedRoute;
И моя функция isRightUser
. Эта функция отправляет status(401)
, когда данные недействительны для зарегистрированного пользователя:
async isRightUser() {
var result = true;
//get token user saved in localStorage
const userAuth = this.get();
if (userAuth) {
await axios.get('/api/users/user', {
headers: { Authorization: userAuth }
}).catch(err => {
if (!err.response.data.auth) {
//Clear localStorage
//this.clear();
}
result = false;
});
}
return result;
}
Этот код не работает, и я действительно не знаю, почему.
Может быть, мне нужно вызвать мою функцию AuthService.isRightUser()
с помощью await
перед вызовом и поставить мою функцию асинхронно?
Как я могу обновить свой код, чтобы проверить моего пользователя перед доступом к защищенной странице?
Когда вы аннотируете функцию с помощью async
, как вы делали это в AuthService.isRightUser()
, она возвращает Promise
, и вы не обрабатываете ответ метода соответствующим образом.
Как вы предложили, вы можете вызвать метод AuthService.isRightUser()
с помощью await
и аннотировать функцию, которую вы передаете свойству render
, с помощью async
.
Или вы можете обработать ответ AuthService.isRightUser()
с помощью .then()
и .catch()
вместо тернарного оператора.
У меня была такая же проблема, и я решил ее, сделав мой защищенный маршрут классом с отслеживанием состояния.
Внутренний переключатель, который я использовал
<PrivateRoute
path = "/path"
component = {Discover}
exact = {true}
/>
И мой класс PrivateRoute выглядит следующим образом
class PrivateRoute extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
isLoading: true,
isLoggedIn: false
};
// Your axios call here
// For success, update state like
this.setState(() => ({ isLoading: false, isLoggedIn: true }));
// For fail, update state like
this.setState(() => ({ isLoading: false, isLoggedIn: false }));
}
render() {
return this.state.isLoading ? null :
this.state.isLoggedIn ?
<Route path = {this.props.path} component = {this.props.component} exact = {this.props.exact}/> :
<Redirect to = {{ pathname: '/login', state: { from: this.props.location } }} />
}
}
export default PrivateRoute;
У меня есть вызов axios для входа в систему внутри моего компонента входа, который возвращает мне токен и ответ на вход. Как я могу использовать этот вызов из компонента входа в компонент PrivateRoute?
Привет, @bubble-cord. Ваш компонент входа в систему должен быть общедоступным маршрутом, потому что каждый должен иметь возможность войти на страницу входа без аутентификации. После выполнения вызова axios в общедоступном компоненте входа в систему вы можете просто перенаправить пользователя на главную страницу с помощью this.props.history.push('/main')
Идеально ! лучше с классом и реагирующими состояниями.