JWT中使用承载方案的认证头

JWT中使用承载方案的认证头,jwt,passport.js,express-jwt,Jwt,Passport.js,Express Jwt,我正在使用Express、Passport和jsonwebtoken为NodeJS中的一个网站构建一个身份验证系统。 我到处找了,但找不到解决问题的办法 现在我有一个身份验证控制器: module.exports = function() { var strategy = new BearerStrategy(params, function(payload, done) { var decodedToken = jwtDecode(payload) db.default.A

我正在使用Express、Passport和jsonwebtoken为NodeJS中的一个网站构建一个身份验证系统。 我到处找了,但找不到解决问题的办法

现在我有一个身份验证控制器:

module.exports = function() {  
var strategy = new BearerStrategy(params, function(payload, done) {
    var decodedToken = jwtDecode(payload)
    db.default.Account.find({where: {id: decodedToken.id}}).then(account =>{
        if (account) {
            return done(null, {
                id: account.id,
                role: account.role
            })
        } else {
            return done(new Error("User not found"), null)
        }
    })
})

passport.use(strategy)
return {
    initialize: function() {
        return passport.initialize()
    },
    authenticate: function() {
        return passport.authenticate("bearer", cfg.jwtSession)
    }
   }
}
在其中,我使用了一个BearerStrategy,这段代码起作用,因为我的/登录路径为用户包装了一个令牌并返回该令牌

  accountController.post("/login", function(req, res) {
     if (req.body.email && req.body.password) {
     var accEmail = req.body.email
     var accPassword = req.body.password
     db.default.Account.find({where: {email: accEmail, password: 
       accPassword}}).then(account =>{
     if (account) {
        var payload = {
           id: account.id,
           role: account.role
      }
      var token = jwt.sign(payload, cfg.jwtSecret)
      console.log(token)
      res.status(200).json({
          token: 'Bearer ' + token
      })
       } else {
         res.sendStatus(401)
     }
   })
 } else {
     res.sendStatus(401)
   }
})
如果我使用Postman发送一个HTTP请求,试图访问路由/帐户,并且我将创建的令牌设置为header,那么一切正常

accountController.get('/account', auth.authenticate('bearer', { session: false }), function(req, res){
res.status(200).render('pages/homepage')
})
我无法回答的问题是: 仅仅用res.json({token:token})发送回令牌是不够的,令牌需要存储在某个地方,对吗?我应该如何使用RestAPI存储令牌,而且,我应该如何在每个请求中从HTTP头内的客户端发送令牌

我愿意听取关于如何在存储和发送JWT之间建立这种联系的建议(因为JWT工作的生成和验证)
谢谢你

是的,像那样发送代币就足够了。您只需确保客户端以某种方式接收令牌。在您的特定情况下,客户端将向
/login
端点发送POST请求,并从对请求的响应中读取令牌。在半伪代码(客户端Javascript)中:

客户端存储令牌。它要么储存在饼干里,要么储存在饼干里。对于不同的存储位置,有不同的选择。必须对客户端进行编程以将其存储在其中一个位置,而服务器根本不存储它。如果您使用的是Angular或React等前端框架,您可以使用Google和“Angular、jwt、Storage”等搜索词找到大量信息和示例。如果您使用的是vanilla JS,您可以按照提供的链接中的示例进行操作。基于上述半伪代码:

http.post('/login', (response) => {
  let token = response.split(' ')[1];
  localStorage.setItem('token', token);
});
令牌与HTTP头(称为授权)中的每个请求一起发送。标题应具有以下格式

Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
那个男孩。。。东西才是真正的象征。在您的情况下,您可能必须使用Bearner(非大写的b),因为您已经设置了Passport以这种方式使用它。您还可以在代码中使用
auth.authenticate('Bearer'),…
,使其更“正确”。在旧文档和博客文章中,您经常可以看到JWT而不是Bearer,但这并不真正符合事实标准

如果您以这种方式发送,Passport应该正确读取令牌

如何在客户端中添加授权标头取决于您是否使用框架,以及客户端是否为浏览器。如果您使用的是vanilla JS,则可以阅读链接。如果您使用的是框架,则可以使用google“set Authorization header,angular”或者类似的东西。通常在官方文档和博客文章中都有大量信息。如果使用前端框架,添加授权字段的代码部分通常称为身份验证拦截器。拦截器有点像中间件

最后,您要写的是:

我应该如何使用RestAPI存储令牌


REST并不真正关心令牌的存储方式。它是在客户端完成的,与REST无关。但是,REST关心端点的名称。如果它是动词,那么
/login
真的是正确的名称吗?问题会被询问和回答。

是的,这样发送令牌就足够了。你只需要确保客户端以某种方式接收令牌。在您的特定情况下,客户端将向
/login
端点发送POST请求,并从对请求的响应中读取令牌。在半伪代码(客户端Javascript)中:

客户端存储令牌。令牌可以存储在中,也可以存储在cookie中。不同的存储位置都有不同的令牌。客户端必须编程将令牌存储在其中一个位置,而服务器根本不存储令牌。如果您使用Angular或React等前端框架,您可以使用Google找到大量信息和示例和搜索词,如“angular、jwt、Storage”。如果您使用的是vanilla JS,您可以按照提供的链接中的示例进行操作。基于上面的半伪代码:

http.post('/login', (response) => {
  let token = response.split(' ')[1];
  localStorage.setItem('token', token);
});
令牌与HTTP标头(称为Authorization)中的每个请求一起发送

Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
ey…东西是实际的令牌。在您的情况下,您可能必须使用Bear(非大写b),因为您已经设置了Passport以这种方式使用它。您还可以在代码中使其
auth.authenticate('Bear'),…
,以使其更“正确”.在较旧的文档和博客文章中,您经常可以看到JWT而不是Bear,但这并不真正符合事实标准

如果您以这种方式发送,Passport应该正确读取令牌

如何在客户端中添加授权标头取决于您是否使用框架,以及客户端是否为浏览器。如果您使用的是vanilla JS,则可以阅读链接。如果您使用的是框架,则可以使用google“set Authorization header,angular”或者类似的东西。通常在官方文档和博客文章中都有大量信息。如果使用前端框架,添加授权字段的代码部分通常称为身份验证拦截器。拦截器有点像中间件

最后,您要写的是:

我应该如何使用RestAPI存储令牌

REST并不真正关心令牌的存储方式。它是在客户端完成的,与REST无关。但是,REST关心端点的名称。如果它是动词,那么
/login
真的是正确的名称吗?问题被询问并回答