Я внедряю простую систему аутентификации пользователей, использующую реагирование js и узел js api.Это то, что я делаю внутри ComponentWillMount метода: -
1.проверка, если токен выходит (в localStorage)
2.Если он не выходит, то значение состояния'token' останется пустым
3.Если он существует, то проверяется, действителен ли он, используя запрос к бэкенду.
4.Если токен действителен, тогда укажите 'token' как localstorage.token
5.Ifтокен недействителен, тогда значение состояния «токен» останется пустым
в методе рендеринга. Я добавил условный рендеринг, основанный на значении состояния «токен», т. е. если состояние «токен» пустотогда будет отображаться обычная страница, в противном случае она будет перенаправлена на страницу пользователя.
Проблема в том, что я могу изменить значение состояния 'token' с помощью любого инструмента разработчика реакции.И это вызывает лазейку при входе в систему с использованием поддельного токена. Чтобы избежать необходимости проверять правильность состояния «токен» каждый раз, когда оно изменяется, с помощью одного из методов жизненного цикла, таких как componentDidUpdate shouldComponentUpdate .Но, как уже упоминалось в официальной документации о реакции
shouldComponentUpdate существует только в качестве оптимизации производительности.Не полагайтесь на него, чтобы «предотвратить» рендеринг, так как это может привести к ошибкам.
Использование componentDidUpdate бесполезно, так как будет вызвано после того, как компонент уже будетизменено из-за изменения состояния.
Использование componentWillUpdate упоминается как небезопасное в официальной документации
Я не уверен, как я могу решить эту лазейку.Вот код для компонента
import React,{Component} from 'react';
import {
BrowserRouter as Router,
Route,
Link,
Switch,
Redirect
} from 'react-router-dom';
import Home from './Home';
import Nav from './Nav';
import Login from './Login';
import Signup from './Signup';
class Out extends Component{
constructor(){
super();
this.state = {
token : '',
isLoading:false
}
this.isLoading = this.isLoading.bind(this);
}
logout(){
alert('logged out');
}
componentWillMount(){
let {match} = this.props;
this.navNoSessionRouteData = [
{to:`${match.url}login`,name:'Login',key:'r1'},
{to:`${match.url}signup`,name:'signup',key:'r2'},
{to:`${match.url}`,name:'Home',key:'r3'}
];
this.navNoSessionButtonData = [];
this.setState({
isLoading:true
});
const tokenVar = localStorage.getItem('token');
if(tokenVar == null){
console.log('not logged in');
this.setState({
isLoading:false
});
}else{
fetch('http://localhost:3000/api/account/verify?token='+tokenVar)
.then(res=>res.json())
.then(json=>{
if(json.success){
console.log('logged in');
this.setState({
token : tokenVar,
isLoading:false
});
}else{
this.setState({
isLoading:false,
});
}
});
}
}
isLoading(){
let {isLoading,token} = this.state;
if(isLoading === true){
return (
<p>Loading...</p>
);
}
else{
let {match} = this.props
console.log(token);
return(
<div>
{
(token)?<p>Logged In</p>:(<p>NOT logged IN</p>)
}
<div className = "row">
<Nav navRouteData = {this.navNoSessionRouteData} navButtonData = {this.navNoSessionButtonData}/>
</div>
<div className="row justify-content-center">
<Switch>
<Route exact = {true} path={`${match.path}`} component={Home} />
<Route path={`${match.path}login`} component={Login}/>
<Route path={`${match.path}signup`} component={Signup}/>
</Switch>
</div>
</div>
)
}
}
render(){
return(
<div>
{this.isLoading()}
</div>
)
}
}
export default Out;