无法在 Node JS 中使用 JWT 访问受保护的路由

Posted

技术标签:

【中文标题】无法在 Node JS 中使用 JWT 访问受保护的路由【英文标题】:Unable to access protected routes using JWT in NodejJS 【发布时间】:2021-08-04 09:39:38 【问题描述】:

我正在尝试使用 jwt 保护应用程序路由。我能够生成 jwt 并验证 jwt 我创建了中间件 authorize.js,并将其传递给 /sec 在下面的代码中路由,但是当我尝试使用 jwt 访问受保护的路由时,它显示以下错误:

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:518:11)
at ServerResponse.header (D:\Backend\NodeJs\aws_test\node_modules\express\lib\response.js:771:10)
at ServerResponse.send (D:\Backend\NodeJs\aws_test\node_modules\express\lib\response.js:170:12)
at ServerResponse.json (D:\Backend\NodeJs\aws_test\node_modules\express\lib\response.js:267:15)
at D:\Backend\NodeJs\aws_test\server.js:24:9
at Layer.handle [as handle_request] (D:\Backend\NodeJs\aws_test\node_modules\express\lib\router\layer.js:95:5)
at next (D:\Backend\NodeJs\aws_test\node_modules\express\lib\router\route.js:137:13)
at D:\Backend\NodeJs\aws_test\auth.js:21:20
at Object.module.exports [as verify] (D:\Backend\NodeJs\aws_test\node_modules\jsonwebtoken\verify.js:53:12)
at authorize (D:\Backend\NodeJs\aws_test\auth.js:11:13)

下面是我在 POSTMAN 中设置 jwt 的方法:

下面是我的代码:

server.js

const express = require('express');
const jwt = require('jsonwebtoken');
const authorize = require('./auth');
const chalk = require('chalk');

const app = express();

const port = 3000 || process.env.PORT;

app.get('/',(req,res) => 

   res.send("Home page");
);

app.get('/jwt',(req,res) => 

   let token = jwt.sign("body":"stuff","mypassphrase", algorithm: 'HS256');
   console.log(chalk.blue(token));
);

app.get('/sec',authorize,(req,res) => 

   res.json("name":"Hello digi");
);

app.listen(port,(req,res) => 

  console.log(chalk.green(`App is running at $port`));
);

auth.js

const fs =  require('fs');
const jwt = require('jsonwebtoken');

authorize = (req,res,next) => 

  if(typeof req.headers.authorization !== "undefined")

      let token = req.headers.authorization.split(" ")[1];
      let key = fs.readFileSync('./private.pem','utf-8');

      jwt.verify(token, key, algorithm: "HS256" ,(err,user) => 

         if (err)   
            // shut them out!
            res.json( error: "Not Authorized" );
           // throw new Error("Not Authorized");
         
          // if the JWT is valid, allow them to hit
         // the intended endpoint
          return next();
       );
  
 else

    // No authorization header exists on the incoming
    // request, return not authorized and throw a new error 
    res.json( error: "No Authorization header" );
   // throw new Error("Not Authorized");

        


module.exports = authorize;

我在上面的代码中做错了什么或需要正确的地方。

【问题讨论】:

【参考方案1】:

看起来可能导致您看到的错误的唯一执行路径如下 - 在autorize 中间件中:

     if (err)   
        res.json( error: "Not Authorized" );  // you're not returning here
     

     return next();

如果此处发生错误,当向客户端发送回响应时,您不会将执行返回给调用代码,因此当前请求会被转发到行中的下一个中间件 - 这最终会导致另一个正在发送响应。

至于首先执行此路径的原因,从您的 Postman 屏幕抓取来看,您为 Authorization 标头设置的值看起来可能不正确 - 您将值设置为jwt,以及对实际 token 的描述,而您实际上希望将值设置为两者的组合,由空格分隔,如 jwt token

【讨论】:

以上是关于无法在 Node JS 中使用 JWT 访问受保护的路由的主要内容,如果未能解决你的问题,请参考以下文章

访问受 EJS 保护的 JWT 路由

如何将 jwt 令牌发送到 node.js 中的受保护路由

无法使用 passport-jwt 访问受保护的路线

Node.js API 受 Keycloak 保护,访问类型为“仅承载”

保护 Express API

如何将 JWT 令牌发送到 node.js 服务器