San*_*pta 9 javascript cookies node.js reactjs redux
如何在我们的 React 应用程序中获取 JWT cookie,如何检查用户是否登录我无法找到如何处理我的 React 应用程序会话。
我真的很感谢谁帮助我解决这个问题。
提前致谢
服务器端API正在设置HTTPOnly您无法在JS中读取的cookie。您需要在您的 React 应用程序中执行此操作,处理401状态错误,并根据该错误设置标志isAuthenticated或其他内容为 false。否则请保持真实。每个对服务器的请求HTTPOnly都会自动发送 cookie,因此您无需处理 cookie 中的令牌。401一旦 cookie 过期,或者请求注销,或者 cookie 中的 JWT 过期,后端代码需要发送 a 。
在我说什么之前,你已经包括app.use(cookieParser())在内了,index.js对吧?因为如果没有,一旦你安装了它,你就会需要它npm i cookie-parser
但无论如何,有几点:
您可以在 React 中创建PrivateRoute,据我所知,这往往可以很好地保护路由免受未经授权的用户的攻击。
您可以简单地将 an 存储isAuthenticated在 或 中state:localStorage但是,这需要您绝对确保用户不能仅更改state或 添加isAuthenticated中的值localStorage并欺骗真实性(这是我的部分最长才能正确)。
不管怎样,我处理这个问题的方法是,当用户登录时,从服务器生成一个access token(refresh 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在我所拥有的时间内正常工作,但两者都应该没问题。
希望这有帮助。
| 归档时间: |
|
| 查看次数: |
16194 次 |
| 最近记录: |