首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于JWT的Next.js认证

基于JWT的Next.js认证
EN

Stack Overflow用户
提问于 2021-02-27 13:00:42
回答 2查看 19.9K关注 0票数 18

我正在将一个项目从React转移到Next.js,并想知道相同的身份验证过程是否正常。基本上,用户输入他们的用户名和密码,并通过API (Node.js/Express)对照数据库凭证进行检查。因此,我不是使用Next.js内部api功能,而是使用与我的Next.js项目完全解耦的API。

如果登录凭据正确,将向客户端发送一个JWT令牌。我想把它存储在本地存储中,然后重定向用户。任何未来的HTTP请求都将在报头中发送令牌,并通过API检查它是否有效。这样可以吗?我问这个问题是因为我看到很多Next.js使用cookies或会话,并且不知道这是否是我应该采用的“标准”方法。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-03-04 01:43:22

我的答案完全是基于我的经验和我所读到的东西。如果我恰巧错了,请随时纠正。

因此,我的方法是将您的令牌存储在HttpOnly cookie中,并始终使用该cookie通过Authorization头授权您对Node的请求。我碰巧在我自己的项目中也使用了Node.js API,所以我知道发生了什么。

下面是我通常如何使用Next.js和Node.js API处理身份验证的一个示例。

为了简化身份验证问题,我在页面中使用内置于getServerSideProps函数中的Next.js来构建一个新的可重用高级组件,该组件将负责身份验证。在本例中,我将将其命名为isLoggedIn

代码语言:javascript
复制
// 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,作为个人资料页面。

代码语言:javascript
复制
// 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,
    },
  },
});

这应该是安全的,因为操纵服务器端的任何东西几乎是不可能的,除非有人设法破解你的后端。

如果你想发邮件,我通常是这样做的。

代码语言:javascript
复制
// 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请求。

票数 18
EN

Stack Overflow用户

发布于 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中,“发布:客户端的令牌存储”:

  • Automatically由浏览器发送(Cookie storage).
  • Retrieved,即使浏览器被重新启动(在出现XSS问题时使用浏览器localStorage container).
  • Retrieved ) (Cookie可访问JavaScript代码或存储在浏览器本地/会话存储中的令牌)。

“如何防止:”

当向令牌调用services.

  • Add指纹信息时,
  • 使用浏览器sessionStorage将令牌存储为带有JavaScript的比勒HTTP身份验证标头。

通过将令牌存储在浏览器sessionStorage容器中,它将令牌暴露为通过XSS攻击被盗的令牌。但是,添加到令牌中的指纹阻止攻击者在其机器上重用被盗令牌。若要关闭攻击者的最大攻击面,请添加浏览器内容安全策略以强化执行上下文。

"FingerPrint“

,其中指纹是实现令牌侧劫持问题的以下准则:此攻击发生在攻击者截获/窃取令牌并使用目标用户身份访问系统时。

“如何预防”:

防止这种情况的一种方法是在令牌中添加“用户上下文”。用户上下文将由以下信息组成:

  • 将在身份验证阶段生成随机字符串。它将作为硬化的cookie (标志: HttpOnly + Secure + SameSite + cookie前缀)发送给客户端。

  • 随机字符串的SHA256散列将存储在令牌中(而不是原始值),以防止任何XSS问题,从而允许攻击者读取随机字符串值并设置预期的cookie.

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66399063

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档