如何在我们的 React 应用程序中获取 JWT cookie,如何检查用户是否登录我无法找到如何处理我的 React 应用程序会话

San*_*pta 9 javascript cookies node.js reactjs redux

如何在我们的 React 应用程序中获取 JWT cookie,如何检查用户是否登录我无法找到如何处理我的 React 应用程序会话。

我真的很感谢谁帮助我解决这个问题。

提前致谢

Pav*_*van 6

服务器端API正在设置HTTPOnly您无法在JS中读取的cookie。您需要在您的 React 应用程序中执行此操作,处理401状态错误,并根据该错误设置标志isAuthenticated或其他内容为 false。否则请保持真实。每个对服务器的请求HTTPOnly都会自动发送 cookie,因此您无需处理 cookie 中的令牌。401一旦 cookie 过期,或者请求注销,或者 cookie 中的 JWT 过期,后端代码需要发送 a 。


nox*_*nox 5

在我说什么之前,你已经包括app.use(cookieParser())在内了,index.js对吧?因为如果没有,一旦你安装了它,你就会需要它npm i cookie-parser

但无论如何,有几点:

  1. 您可以在 React 中创建PrivateRoute,据我所知,这往往可以很好地保护路由免受未经授权的用户的攻击。

  2. 您可以简单地将 an 存储isAuthenticated在 或 中statelocalStorage但是,这需要您绝对确保用户不能仅更改state或 添加isAuthenticated中的值localStorage并欺骗真实性(这是我的部分最长才能正确)。


不管怎样,我处理这个问题的方法是,当用户登录时,从服务器生成一个access tokenrefresh token如果它不存在的话,则为一个)并以httpOnlycookie 形式发送到客户端,而这使得您可以正如Pavan在他的回答中指出的那样,不要在客户端使用 JavaScript 对其执行任何操作(这通常是一件好事),您应该res.status在发出fetch请求时用于验证。这是我的fetch请求的样子:

const login = async (user) => {
        const body = JSON.stringify(user);
        return fetch(loginURL, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Accept': 'application/json'
            },
            credentials: 'include', //this is important
            body: body
        }).then(function(res) {
            if (res.status === 200) {
                const id = Date.now();
                localStorage.sid = id; //this is temporary
                return res.json()
            } else {
                return res.json()
            }
        })
         // you can ignore this part
        .then(async resp => {
            return resp
        })
}
Run Code Online (Sandbox Code Playgroud)

旁注:您的浏览器会自动处理httpOnly您从服务器发送的 cookie,但credentials: 'include' 需要将其包含在您的后续fetch请求中。

在我的主要父组件之一中,该login函数被调用:

login = async (user) => {
  this.setState({ error: null });
  await adapter.login(user).then(data => {
    if (!data.error) {
      this.setState({session: "active"})
    } else if (data.error && data.error.status === 401) {
        // this is so I can handle displaying invalid credentials errors and stuff
        this.setState({ error: data.error, loading: false });
    }
  });
}
Run Code Online (Sandbox Code Playgroud)

我还在middleware服务器端运行了一个在路由中的任何代码之前运行的代码,以验证发出请求的用户是否确实获得了授权。这也是access token我处理过期的原因;如果access token已过期,我会使用refresh token生成一个新的access token并将其发送回httpOnlycookie 中,状态再次为 200,这样用户体验就不会感到不舒服。这当然意味着你refresh token必须比你活得更久access token(我还没有决定我的情况是多长时间,但我想是 7 天或 14 天),但据我所知,这是可以的做。

最后一件事,我之前提到的父组件调用一个验证函数,该函数是fetch向其内部的服务器发出的请求componentDidMount,以便每次安装组件时都会验证用户,然后我添加了一些条件渲染:

    render() {
        return (
          <div className="container">
          {
            !localStorage.sid && <LoginForms {...yourPropsHere}/>
          }       
          {
            this.state.loading && <Loading />
          }
          {
            localStorage.sid && this.state.session === "active" && <Route path="/" render={(props) => <Root error={this.state.error} {...props}/>}/>
          }
          </div>
        );
    }
Run Code Online (Sandbox Code Playgroud)

我已经采用了条件渲染路线,因为我无法PrivateRoute在我所拥有的时间内正常工作,但两者都应该没问题。

希望这有帮助。