我正在将一个项目从React转移到Next.js,并想知道相同的身份验证过程是否正常。基本上,用户输入他们的用户名和密码,并通过API (Node.js/Express)对照数据库凭证进行检查。因此,我不是使用Next.js内部api功能,而是使用与我的Next.js项目完全解耦的API。
如果登录凭据正确,将向客户端发送一个JWT令牌。我想把它存储在本地存储中,然后重定向用户。任何未来的HTTP请求都将在报头中发送令牌,并通过API检查它是否有效。这样可以吗?我问这个问题是因为我看到很多Next.js使用cookies或会话,并且不知道这是否是我应该采用的“标准”方法。
发布于 2021-03-04 01:43:22
我的答案完全是基于我的经验和我所读到的东西。如果我恰巧错了,请随时纠正。
因此,我的方法是将您的令牌存储在HttpOnly cookie中,并始终使用该cookie通过Authorization头授权您对Node的请求。我碰巧在我自己的项目中也使用了Node.js API,所以我知道发生了什么。
下面是我通常如何使用Next.js和Node.js API处理身份验证的一个示例。
为了简化身份验证问题,我在页面中使用内置于getServerSideProps函数中的Next.js来构建一个新的可重用高级组件,该组件将负责身份验证。在本例中,我将将其命名为isLoggedIn。
// isLoggedIn.jsx
export default (GetServerSidePropsFunction) => async (ctx) => {
// 1. Check if there is a token in cookies. Let's assume that your JWT is stored in 'jwt'.
const token = ctx.req.cookies?.jwt || null;
// 2. Perform an authorized HTTP GET request to the private API to check if the user is genuine.
const { data } = await authenticate(...); // your code here...
// 3. If there is no user, or the user is not authenticated, then redirect to homepage.
if (!data) {
return {
redirect: {
destination: '/',
permanent: false,
},
};
}
// 4. Return your usual 'GetServerSideProps' function.
return await GetServerSidePropsFunction(ctx);
};getServerSideProps会阻止呈现,直到函数被解析为止,所以请确保您的身份验证是快速的,并且不会浪费太多时间。
您可以像这样使用高阶组件。让我们把这个叫做profile.jsx,作为个人资料页面。
// profile.jsx
export default isLoggedIn(async (ctx) => {
// In this component, do anything with the authorized user. Maybe getting his data?
const token = ctx.req.cookies.jwt;
const { data } = await getUserData(...); // don't forget to pass his token in 'Authorization' header.
return {
props: {
data,
},
},
});这应该是安全的,因为操纵服务器端的任何东西几乎是不可能的,除非有人设法破解你的后端。
如果你想发邮件,我通常是这样做的。
// profile.jsx
const handleEditProfile = async (e) => {
const apiResponse = await axios.post(API_URL, data, { withCredentials: true });
// do anything...
};在POST请求中,HttpOnly cookie也将发送到服务器,因为withCredentials参数被设置为true。
还有一种使用Next.js的无服务器API将数据发送到服务器的替代方法。不是向API发出POST请求,而是向'proxy‘Next.js的无服务器API发出POST请求,在那里它将对API执行另一个POST请求。
发布于 2022-03-03 20:48:16
没有标准的方法。你应该担心安全问题。我看了这篇博文:https://hasura.io/blog/best-practices-of-using-jwt-with-graphql/
这是一篇很长但很棒的博客文章。我在这里发表的每一篇文章都会被引用:
如果一个JWT被偷,那么小偷可以继续使用JWT。接受JWT的API可以进行独立的验证,而不依赖于JWT源,因此API服务器无法知道这是否是被盗的令牌!这就是为什么JWT有一个到期值。而且这些值都很短。通常的做法是保持在15分钟左右。
当服务器发送令牌时,必须持久化地将JWT存储在客户机上。
使您的应用程序易受CSRF和XSS攻击,通过恶意表单或脚本使用或窃取您的令牌。我们需要将JWT令牌保存在某个地方,以便将其作为头转发到API。您可能会倾向于将它保存在本地存储中,不要这样做!这很容易受到XSS攻击。
把它保存在饼干里怎么样?
在客户机上创建cookies以保存JWT的
也很容易使用XSS。如果它可以从你的应用程序之外的Javascript读取到客户端,那么它可能会被偷。您可能认为HttpOnly cookie (由服务器而不是客户端创建)会有所帮助,但cookie很容易受到CSRF攻击。需要注意的是,HttpOnly和合理的CORS策略不能防止CSRF表单提交攻击,使用cookie需要适当的CSRF缓解策略。
请注意,SameSite cookie将使基于Cookie的方法免受CSRF攻击。如果您的Auth和API服务器托管在不同的域上,这可能不是一个解决方案,但如果不是这样的话,它应该工作得很好!
那我们要把它保存在哪里?
、OWASP、Cheatsheet和OWASP (应用程序安全验证标准)规定了处理和存储令牌的准则。
与此相关的部分是JWT Cheatsheet中的客户端令牌存储和令牌侧插入问题,以及ASVS的第3章(会话管理)和第8章(数据保护)。
在Cheatsheet中,“发布:客户端的令牌存储”:
“如何防止:”
当向令牌调用services.
通过将令牌存储在浏览器sessionStorage容器中,它将令牌暴露为通过XSS攻击被盗的令牌。但是,添加到令牌中的指纹阻止攻击者在其机器上重用被盗令牌。若要关闭攻击者的最大攻击面,请添加浏览器内容安全策略以强化执行上下文。
"FingerPrint“
,其中指纹是实现令牌侧劫持问题的以下准则:此攻击发生在攻击者截获/窃取令牌并使用目标用户身份访问系统时。
“如何预防”:
防止这种情况的一种方法是在令牌中添加“用户上下文”。用户上下文将由以下信息组成:
。
https://stackoverflow.com/questions/66399063
复制相似问题