【问题标题】:is it safe to use react js state to store token of authenticated user?使用 React js 状态存储经过身份验证的用户的令牌是否安全?
【发布时间】:2019-03-12 23:02:46
【问题描述】:

我正在使用 react js 和 node js api 实现一个简单的用户认证系统。这就是我在 ComponentWillMount 方法中所做的:-

1.检查令牌是否退出(在localStorage中)
2.如果它没有退出,那么状态'token'的值将保持空白
3.如果存在,则使用后端请求检查它是否有效。
4.如果令牌有效,则将“令牌”声明为 localstorage.token
5.如果令牌无效,则状态“令牌”的值将保持空白

在渲染方法中,我添加了基于状态“token”值的条件渲染,即如果状态“token”为空白,则将渲染普通页面,否则将重定向到用户页面。

问题是我可以使用任何反应开发工具更改状态“令牌”的值。这导致了使用假令牌登录的漏洞。为避免每次使用诸如 componentDidUpdate shouldComponentUpdate 之类的生命周期方法之一更改状态“令牌”时,我都必须检查它的有效性。但正如 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;

【问题讨论】:

  • 既然假令牌不管用,真的有问题吗?令牌需要存储在某个地方,用户可以更改它,无论它是如何存储的。
  • 我什至不确定这是一个漏洞。最坏的情况是用户会弄乱自己的令牌并需要再次进行身份验证。
  • 如果我想提供一些我希望只有登录用户可以访问的服务并且那些应该为假令牌隐藏的服务,这是一个问题
  • 任何未登录的用户都可以在状态“令牌”中添加任何值,并且将能够看到隐藏的内容。
  • 好吧,如果您要接受任何令牌,因为它们是假的,您无法真正阻止他们这样做。如果您将信息存储在客户端,无论您如何操作,确定的用户都会找到改变它的方法。

标签: javascript reactjs authentication authorization react-lifecycle


【解决方案1】:

只是在这里循环,我会用两个问题来回答这个问题:

(我认为更接近您的问题):如果我可以编辑 React 状态变量,我显示的任何内容如何安全?

这里的重点是他们可以导航到要求他们登录的 UI,但是当他们实际去请求数据时(无论是到您的后端,还是直接到您的数据库,如 Firebase),那么他们将需要一个有效的令牌来这样做。您的后端应该对此进行检查,并且不会返回任何有价值的数据。

如果我可以读取 React 状态变量,那么我的令牌不会被盗用并被其他人用来请求和写入数据的安全性如何?

对此,请参阅this answer

【讨论】:

    猜你喜欢
    • 2010-09-27
    • 2020-09-28
    • 1970-01-01
    • 1970-01-01
    • 2016-11-30
    • 2015-02-06
    • 2013-02-12
    • 2018-06-07
    • 2016-12-18
    相关资源
    最近更新 更多