【问题标题】:Losing JWT token after browser refresh浏览器刷新后丢失 JWT 令牌
【发布时间】: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;

【问题讨论】:

    标签: reactjs spring-boot jwt


    【解决方案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,我有一个带有这种身份验证流程设置的小型样板项目。希望这会有所帮助,祝您编码愉快!

    【讨论】:

      猜你喜欢
      • 2021-06-28
      • 2020-11-19
      • 1970-01-01
      • 2011-02-01
      • 2021-06-23
      • 2014-05-31
      • 2016-03-05
      • 2016-06-25
      • 2021-04-13
      相关资源
      最近更新 更多