浏览器刷新后丢失 JWT 令牌

Posted

技术标签:

【中文标题】浏览器刷新后丢失 JWT 令牌【英文标题】:Losing JWT token after browser refresh 【发布时间】:2019-03-24 12:58:45 【问题描述】:

我正在学习 Full Stack Development with Spring Boot 2.0 and React 。 身份验证和授权由 JWT 管理,应用程序按预期工作,但刷新浏览器后我必须重新登录。 浏览器刷新后如何维护 JWT 令牌?

import React,  Component  from 'react';
    import TextField from '@material-ui/core/TextField';
    import Button from '@material-ui/core/Button';
    import Snackbar from '@material-ui/core/Snackbar';
    import Carlist from './Carlist';
    import SERVER_URL from '../constants.js';

    class Login extends Component 
      constructor(props) 
        super(props);
        this.state = username: '', password: '', isAuthenticated: false, open: false;
      

      logout = () => 
        sessionStorage.removeItem("jwt");
        this.setState(isAuthenticated: false);
    

      login = () => 
        const user = username: this.state.username, password: this.state.password;
        fetch(SERVER_URL + 'login', 
          method: 'POST',
          body: JSON.stringify(user)
        )
        .then(res => 
          const jwtToken = res.headers.get('Authorization');
          if (jwtToken !== null) 
            sessionStorage.setItem("jwt", jwtToken);
            this.setState(isAuthenticated: true);
          
          else 
            this.setState(open: true);  // maintient snackbar ouvert
          
        )
        .catch(err => console.error(err))
      

      handleChange = (event) => 
        this.setState([event.target.name] : event.target.value);
      

      handleClose = (event) => 
        this.setState( open: false );
      

      render() 
        if (this.state.isAuthenticated === true) 
          return (<Carlist />)
        
        else 
          return (
            <div>
              <br/>
              <TextField tpye="text" name="username" placeholder="Username"
              onChange=this.handleChange /><br/>
              <TextField type="password" name="password" placeholder="Password"
              onChange=this.handleChange /><br /><br/>
              <Button variant="raised" color="primary" onClick=this.login>Login</Button>
              <Snackbar
              open=this.state.open  onClose=this.handleClose
              autoHideDuration=1500 message='Check your username and password' />
            </div>
          );
        
      
    

    export default Login;

【问题讨论】:

【参考方案1】:

我会使用本地存储而不是像这样的会话存储

localStorage.setItem("jwt", jwtToken)

而不是行

sessionStorage.setItem("jwt", jwtToken);

在开发控制台中检查本地存储,刷新页面看看是否还在。它可能需要在您的身份验证流程中进行一些其他更改才能从 localStorage 而不是 sessionStorage 构建它;但是,这将解决在页面刷新时丢失 jwt 的直接问题。

【讨论】:

本地存储(承载)仍在开发控制台中,但应用重定向到登录页面。 嗨,在我登录我的服务器后处理重定向。我刚刚检查了我的快递服务器和res.redirect(`http://www.localhost:3001/`);,这是我处理重定向到我的登录页面而不是登录页面的行。 这不安全。请参阅客户端的令牌存储部分 - cheatsheetseries.owasp.org/cheatsheets/…【参考方案2】:

我认为您根本不检查构造函数中本地存储中的令牌。当您重新加载页面时,您的构造函数会执行并设置isAuthenticated = false,无论本地存储中是否存在令牌。在最终设置isAuthenticated 之前,您应该添加额外的逻辑来检查本地存储中的令牌。放置此代码的最佳位置可能是componentDidMount() 函数。我的意思是最初将其设置为 false,然后根据当前授权状态在 componentDidMount() 中更新。看看我的GitHub,我有一个带有这种身份验证流程设置的小型样板项目。希望这会有所帮助,祝您编码愉快!

【讨论】:

以上是关于浏览器刷新后丢失 JWT 令牌的主要内容,如果未能解决你的问题,请参考以下文章

刷新后如何使以前的 JWT 令牌无效

黑名单/验证/生成 JWT 刷新令牌

刷新令牌如何比长寿命的 JWT 更安全?

为啥不将 JWT 访问令牌存储在内存中并在 cookie 中刷新令牌?

用于 JWT 刷新令牌的 react-native 中的 httpOnly cookie

同时从移动设备和 Web 刷新 JWT 令牌的最佳实践