我正在使用react js和node js api实现一个简单的用户身份验证系统。这就是我在 ComponentWillMount 方法中执行的操作:-
1。检查令牌是否退出(在localStorage中)
2.如果未退出,则状态“令牌”的值将保持空白
3.如果存在,则使用后端请求检查其是否有效。
4.如果令牌有效,则将“令牌”声明为localstorage.token
5.如果令牌无效,则状态“令牌”的值将保持空白
在内部渲染方法中,我基于状态'token'的值添加了条件渲染,即,如果状态'token'为空白,则将渲染普通页面,否则它将被重定向到用户页面。
问题是,我可以使用任何react开发人员工具来更改状态“令牌”的值。这就造成了使用伪造令牌登录的漏洞。为避免这种情况,每次使用状态更改方法之一,例如 componentDidUpdate shouldComponentUpdate 时,我都必须检查状态'token'的有效性。但是正如react的官方文档所述, 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;
答案 0 :(得分:1)
只需在这里循环,我将用两个问题回答这个问题:
这里的要点是它们可以导航到要求登录的用户界面,但是当他们实际去请求数据(向您的后端,或者直接向您的数据库(如Firebase)请求数据)时,他们将需要一个有效的令牌来这样做。您的后端应对此进行检查,并且不会返回任何有价值的数据。
为此,请参见this answer