JWT 在 Node.JS 中无法正常工作

Posted

技术标签:

【中文标题】JWT 在 Node.JS 中无法正常工作【英文标题】:JWT is not working as expected with Node.JS 【发布时间】:2020-07-25 19:29:28 【问题描述】:

对于Node JS 上的JWT,我很难让事情按应有的方式工作。 首先让我说我的目标是(登录后)访问我的 API 的 privateRoute 路由。

我总是打:

 authHeader == null 

authenticateToken 中间件函数内部,虽然我已经尝试了很多东西。

所以我无法通过 authenticateToken 的级别让我进入。 作为在标题中引入所需内容并能够通过的解决方案,我曾考虑创建一种进入路径以进入,但它仍然无法正常工作。

这里是相关代码。

app.get('/privateRoute', authenticateToken, function(req, res) 
    // Useful work to do, after logging in.
    .......
);


function authenticateToken(req, res, next) 
  // Gather the jwt access token from the request header
  const authHeader = req.headers['authorization'],
  token = authHeader && authHeader.split(' ')[1]

  if (token == null) 
    console.log('authenticateToken-401')
    return res.sendStatus(401) // There isn't any token.
  
  // It never reaches this point !!!

  jwt.verify(token, 'myBigSecret', (err, user) => 
    console.log(err)
    if (err) 
      console.log('authenticateToken-403')
      return res.sendStatus(403)
    
    req.user = user
  )



app.get('/entryRoute', function(req, res) 
  res.set('authorization', 'Bearer ' + myJWT_Token);
  res.redirect('/privateRoute');
);

有人能告诉我我需要对代码进行哪些更改以使我的(可能不太好的)解决方案能够正常工作吗?或者告诉我一个更好的方法?

以下是来自浏览器的一些额外信息,以备不时之需。

在 FireFox 菜单、工具、Web 开发人员、Web 控制台中;网络选项卡。我可以看到以下内容:

对于响应头(/entryRoute):

Authorization : Bearer eyiwhfehihinR…CuwfihvihiL_hfgSt_J8D
Connection :keep-alive
Content-Length : 56
Content-Type : text/html; charset=utf-8
Date : Mon, 13 Apr 2020 09:46:55 GMT
Location : /privateRoute
Server : Xoibuy
Vary : Accept
Via : 1.1 vegur
X-Powered-By : Express

对于请求头(/privateRoute):

Accept : text/html,application/xhtml+xm…ml;q=0.9,image/webp,*/ *;q=0.8
Accept-Encoding : gzip, deflate, br
Accept-Language : en-US,en;q=0.5
Connection : keep-alive
Host : myapp.herokuapp.com
Upgrade-Insecure-Requests : 1
User-Agent : Mozilla/5.0 (Macintosh; Intel …) Gecko/20100101 Firefox/75.0

【问题讨论】:

你能分享开发者工具的网络选项卡中的请求信息或请求对象的值吗? 我刚刚添加了一些可以在浏览器中找到的信息,希望这是您需要的。请再看一遍帖子,接近尾声。 我可以看到我对Authorization所做的事情并没有传递给privateRoute。这可能只是表明我的做法是错误的。 您必须将 Authorization 标头传递给您的 http 请求,以使其通过您的 AuthenticateToken 中间件 尝试访问它:req.header('Authorization')。此外,您需要在验证后致电next() 以使其进入您的功能 【参考方案1】:

我的声誉仍然很低,所以我无法发表评论。我认为您的代码没有问题。我认为您以错误的方式执行 Http 请求,因为授权标头未传递给请求。我不知道您在前端使用的是什么语言,但我假设它是 javascript。你可以这样做。

const consumeApi() = async () => 
   const response = await fetch('https://example.domain/endpoint', 
      method: 'POST' // could be any other methods (GET, POST, PUT, PATCH, DELETE, etc)
      headers: 
         'Authorization': 'Token some_token_value'
      
   );

   // Response status other than 200
   if (response.status !== 200) return alert('Something wrong happened.'); 

   // Response status 200
   // do someting ...

使用上面的代码,您应该能够将授权标头添加到您的 Http 请求中。希望这会有所帮助。

-- 编辑 您可以尝试创建一个新的 HTML 文件。假设 example.html 看起来像这样

// example.html
<!DOCTYPE html>
<html>
<script>
   const consumeApi() = async () => 
      const response = await fetch('https://example.domain/endpoint', 
         method: 'POST' // could be any other methods (GET, POST, PUT, PATCH, DELETE, etc)
         headers: 
            'Authorization': 'Token some_token_value'
         
      );

      // Response status other than 200
      if (response.status !== 200) return alert('Something wrong happened.'); 

      // Response status 200
      // do someting ...
   

   // call the function directly after loading the HTML page
   consumeApi().then();
</script>
</html>

然后尝试通过网络浏览器打开 example.html 文件,它应该会直接调用您的 api。这样,您应该能够使用 Authorization 标头向您的 node.js 服务器发出请求。希望这会有所帮助

【讨论】:

您的建议看起来很有希望,并且您认为是正确的。我确实在使用 JavaScript。我现在不确定应该在哪里插入您的代码;但我会尝试看看。 我将编辑我的答案,以便您可以立即试用代码 我已尝试使用您在 example.html 中的代码。虽然我取得了一些进展,但似乎缺少了一些东西。因为我在浏览器中永远看不到example.domain/endpoint,这应该是最后发生的事情。 @冷龙。我在日志中看到或检查的所有内容都表明这一切都按预期进行,但由于某种未知原因,浏览器中没有显示任何内容。 如果后端或node.js端工作正常,那么我想没有问题。我上面提供的 html 代码是空的,仅用于测试目的(在这种情况下测试你的 node.js api)。

以上是关于JWT 在 Node.JS 中无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

Node.js 和 Express 排除路由表单 JWT 中间件

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

Node.js和Express排除路由形式JWT中间件

使用 cors、express 和 google api 的 Node.js 服务器应用程序在 Azure 部署后无法正常工作

如何延长node.js中相同jwt令牌的到期时间

Node.js 云功能“get() 中的 firestore set() 如果不存在”无法正常工作?