【问题标题】:JWT Authentication with NextJS使用 NextJS 进行 JWT 身份验证
【发布时间】:2022-12-03 04:29:53
【问题描述】:

我搜索了一下,但没有找到关于这个主题的任何明确的、最新的答案。

我正在尝试在我的 NextJS 应用程序中实施 JWT 身份验证。以下是我到目前为止所拥有的。

  • /login 将 (1) 检查用户/密码是否存在且有效,以及 (2) 基于私有 RS256 密钥创建 JWT 令牌的端点。
  • 创建了一个中间件层来验证 JWT

JWT 的创建很好——它可以很好地从文件系统读取密钥并签署 JWT。

但是,由于边缘运行时(阅读here),我遇到了中间件无法使用节点模块(fspath)的问题。这使得我无法从 FS 读取公钥。

在每个请求上验证 JWT 令牌的正确方法是什么?我读过 fetching from middleware 是不好的做法,应该避免。关于这个主题的所有其他参考资料(我发现的)要么使用“秘密”而不是密钥(因此可以放入 process.env 并在中间件中使用)或掩盖事实(1)。或者我应该只创建一个单独的快速应用程序来处理 JWT 创建/验证?

【问题讨论】:

    标签: node.js reactjs authentication next.js jwt


    【解决方案1】:

    我所做的是在 pages 中添加一个文件 (_middleware.tsx)。这确保文件运行每个页面加载但不被视为标准页面。在这个文件中有一个 Edge 函数。如果用户未登录(cookie 中没有JWT)并尝试访问受保护的页面,他将立即被重定向到/signin在服务器被击中之前.

    import { NextResponse } from "next/server";
    
    const signedInPages = ["/admin", "/members "];
    
    export default function middleware(req) {
      if (signedInPages.find((p) => p === req.nextUrl.pathname)) {
        const { MY_TOKEN: token } = req.cookies;
    
        if (!token) {
          return NextResponse.redirect("/signin");
        }
      }
    }
    
    

    【讨论】:

    • 我已经这样做了,但是有没有办法在中间件函数中验证令牌?边缘 API 阻止某些节点模块运行(例如 FS、路径等)。什么是正确的验证方法?
    【解决方案2】:

    如果您从

    import jwt from "jsonwebtoken";
    

    然后您可以使用相同的jwt 来验证中间件函数内的令牌。您在 pages 目录中创建 _middleware.js,中间件将在请求到达端点之前为每个请求运行:

    import { NextResponse } from "next/server";
    import jwt from "jsonwebtoken";
    
    export async function middleware(req, ev) {
      
      const token = req ? req.cookies?.token : null;
    
      let userId=null;
       if (token) {
         // this is how we sign= jwt.sign(object,secretKey)
         // now use the same secretKey to decode the token
        const decodedToken = jwt.verify(token, process.env.JWT_SECRET);
        userId = decodedToken?.issuer;
      }
       
      const { pathname } = req.nextUrl;
      // if user sends request to "/api/login", it has no token. so let the request pass
      if (
        pathname.includes("/api/login") || userId
      ) {
        return NextResponse.next();
      }
    
      if (!token && pathname !== "/login") {
        return NextResponse.redirect("/login");
      }
    }
    

    【讨论】:

      【解决方案3】:

      您在发布请求标头中发送令牌。

      {Authorization: 'Bearer ' + token}
      

      然后在发回数据之前验证服务器上的令牌

      要验证您创建中间件函数的令牌,然后在您想要传输的任何路由上使用该函数

      router.get("/", middlewarefunction, function (req: any, res: any, next: any) {
        res.send("/api")
      })
      

      【讨论】:

      • 这没有回答我的问题。我已经可以通过(请求)cookie 访问令牌服务器端。我的问题是如何验证服务器上的令牌。
      猜你喜欢
      • 2016-04-07
      • 2023-03-27
      • 2021-05-29
      • 2017-07-30
      • 2018-06-30
      • 2018-08-03
      • 2021-02-06
      • 2015-06-29
      • 2018-08-29
      相关资源
      最近更新 更多