我目前正在开发一个MERN堆栈应用程序,我使用的身份验证是JWT,并将其保存在我的cookie中。
res
.cookie("token", token, {
httpOnly: true,
secure: true,
sameSite: "none",
})
.send();
而且我通过在我的后端获得“令牌”cookie来登录用户。然而,我用这个应用程序实现了Redux,每次我刷新页面时,它会自动退出。我想要的是在我的前端检测(React)我的浏览器中的“token”cookie无法获取。我尝试使用npm js-cookie,但仍然无法获取。是否有方法可以获取“token”cookie?或者根据我读到的内容使用redux-persistent?请帮助,谢谢。
4条答案
按热度按时间n3ipq98p1#
就像其他答案已经解释的那样,你不能通过JS访问httpOnly cookie。
我个人建议你使用不同的方法。当然,cookie和httpOnly听起来是个好主意,你可能认为cookie比localStorage好一千倍,但最终,你是把令牌存储在localStorage还是cookie中并不重要。你可能会为cookie和localStorage争论几个小时,但两者都有它们的漏洞(例如:Cookie:CSRF攻击(https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html),本地存储:XSS)的数据。
现在,虽然理论上可以在这里使用localStorage,但我并不提倡使用它。(可以是context-api、redux等),并将带有身份验证头的JWT发送到后端。当然,后端需要验证该令牌。您可以,例如,只需实现一个身份验证中间件,并将其添加到所有需要身份验证的路由中。过期也非常简单,因为您不必再同步JWT和cookie的过期。只需在JWT上设置过期,身份验证中间件中的令牌验证就会捕获它。如果您想知道为什么此方法可以安全地抵御CSRF攻击,请看这里:Where to store JWT in browser? How to protect against CSRF?
这里有一些好文章,我真的会推荐你读一点的第一个:https://hasura.io/blog/best-practices-of-using-jwt-with-graphql/https://medium.com/@ryanchenkie_40935/react-authentication-how-to-store-jwt-in-a-cookie-346519310e81打印机
t1qtbnec2#
你不能。“httpOnly”意味着“JavaScript不能访问它”。
使用Redux-Persist也不能真正帮助您确定您是否仍处于登录状态或您的会话是否超时。这些数据可能在几周前就已被持久化,或者令牌可能已被吊销。
最明智的做法是在服务器上设置一个
/whoami
端点,并作为应用程序初始化时的第一步,向服务器发送一个请求。要么返回用户信息-〉太好了,保存并显示它。否则,您会得到一个“401未授权”,这意味着用户没有登录,需要登录。68bkxrlz3#
虽然您不能在前端对httpOnly cookie做任何事情,但肯定有一种方法可以处理前端发送的httpOnly cookie,并从该cookie中提取您的JWT,所有这些都在MERN堆栈应用程序的后端。
至于持久化用户并防止"logout upon refresh“问题,您将必须创建一个useEffect钩子来不断地检查令牌是否存在--我们将在后面讨论这个问题。
首先,我建议在后端使用Cors:
准备就绪后,在创建httpOnly cookie时设置以下选项。此外,如果是JWT,则创建一个非httpOnly cookie,它使用相同的过期日期和布尔值跟踪httpOnly cookie。这将允许您使用'universal-cookie'库并实际读取前端中的非httpOnly cookie:
创建了一个模仿我们实际'token'的'checkToken' cookie后,我们可以使用它来设置状态(useState钩子),如果用户存在且未过期,则可以通过useEffect钩子来持久保存用户。
但是,要正确地发送它,我们必须先指定几件事,在这个例子中,我将使用axios在前端进行这样的API调用。
请注意,每个API调用的请求头将包含我们的httpOnly cookie及其内容-我们可以通过打开chrome开发工具的网络选项卡来确认这一点,进行API调用,然后检查“请求头”中的“Cookie”...
完成后,我们可以确认在后端的API调用的请求主体中获得了这样的令牌(无论在哪里处理),在控制台中记录cookie以检查它,然后将cookie的值存储在一个变量中以启用对所述cookie的验证:
好了,好了
请注意,这是一个一般的实现,只是作为一个指南,以了解httpOnly cookie的功能。OP从来没有提供原始代码去关闭。
希望这能帮上忙,祝你成功。
l3zydbqr4#
我们遇到了类似的问题当提高授权工作流的安全性在一个项目上使用React/Django创建时
问题是:存储JWT的最佳位置是什么?
经过研究,我们最终实现了Oauth2协议,本文将帮助您了解Refresh token rotation的逻辑
我们的实施
1.在后端生成2个令牌(访问令牌[短寿命]和刷新令牌[长寿命])
1.刷新标记应存储在HttpOnly cookie中(正如他们在响应中提到的,JS无法在客户端访问它)
1.在前端级别,我们仅使用访问令牌,当它过期时,我们调用后端以重新生成另一个访问和刷新
1.后端将访问HttpOnly Cookie中的刷新令牌,并确定它是否有效,以生成新令牌
1.如果后端生成新的有效令牌,则将访问令牌发送到前端,并更新Cookie中的刷新令牌
Ps:通过这个逻辑,你没有权限在前端刷新令牌,所以当你的访问令牌不再有效时,你告诉服务器检查存储在HttpOnly Cookie中的刷新令牌,如果它仍然有效,然后重新生成其他有效令牌
我希望这能启发你