使用 JWT 承载方案的身份验证 header
Authentication header using bearer scheme for JWT
我正在使用 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 并且此代码有效,因为我的 /login 路由为用户创建了一个令牌,returns 该令牌
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 请求尝试访问路由 /account 并且我设置为 header 创建的令牌一切正常。
accountController.get('/account', auth.authenticate('bearer', { session: false }), function(req, res){
res.status(200).render('pages/homepage')
})
我没能回答的问题是:
用 res.json({token: token}) 发送回令牌是不够的,令牌需要存储在某个地方,对吧?我应该如何使用 RestAPI 存储令牌,此外,我应该如何在每个请求中从 HTTP header 中的 client-side 发送令牌?
我愿意接受有关如何在存储和发送 JWT 之间建立这种联系的建议(自 JWT 工作的生成和验证以来)
谢谢
是的,这样发送令牌就足够了。您只需要确保客户端以某种方式收到令牌。在您的特定情况下,客户端将向 /login
端点发送 POST 请求,并从对请求的响应中读取令牌。在 semi-pseudo 代码中 (client-side Javascript):
http.post('/login', (response) => {
let token = response.split(' ')[1];
});
客户端存储令牌。它存储在 localStorage, sessionStorage or in a cookie. There are pros and cons 中用于各种存储位置。必须对客户端进行编程以将其存储在其中一个位置,而服务器根本不存储它。如果您使用 front-end 框架(例如 Angular 或 React),您可以使用 Google 和搜索词(例如 "angular, jwt, storing")找到大量信息和示例。如果您使用的是普通 JS,则可以按照提供的 link 中的示例进行操作。基于上面的 semi-pseudo 代码:
http.post('/login', (response) => {
let token = response.split(' ')[1];
localStorage.setItem('token', token);
});
令牌与 HTTP header 中称为 Authorization 的每个请求一起发送。 header 应具有以下格式
Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
眼睛...东西是实际的令牌。在您的情况下,您可能必须使用 bearer (non-capitalized b),因为您已经将 Passport 设置为拥有它方法。您也可以在您的代码中将其设为 auth.authenticate('Bearer', ...
,使其更 "correct"。在较旧的文档和博客文章中,您经常可以看到 JWT 而不是 Bearer,但这并不真正遵循 de-facto 标准。
如果您以这种方式发送,Passport 应该可以正确读取令牌。
如何在客户端添加Authorization header取决于您是否使用框架,以及客户端是否是浏览器。如果你使用的是 vanilla JS,你可以阅读 this link。如果您使用的是框架,则可以 google "set authorization header, angular" 或类似的东西。官方文档和博客文章中通常都有大量信息。如果您使用的是 front-end 框架,则添加 Authorization 字段的代码部分通常称为 auth 拦截器。拦截器有点像中间件。
最后,你在写这个:
How should I store the token using a RestAPI...
REST 并不关心令牌的存储方式。它是在客户端完成的,与 REST 无关。但是,REST 关心端点的名称。如果 /login
是一个动词,它真的是正确的名字吗?问题被提出并得到回答 here.
我正在使用 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 并且此代码有效,因为我的 /login 路由为用户创建了一个令牌,returns 该令牌
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 请求尝试访问路由 /account 并且我设置为 header 创建的令牌一切正常。
accountController.get('/account', auth.authenticate('bearer', { session: false }), function(req, res){
res.status(200).render('pages/homepage')
})
我没能回答的问题是: 用 res.json({token: token}) 发送回令牌是不够的,令牌需要存储在某个地方,对吧?我应该如何使用 RestAPI 存储令牌,此外,我应该如何在每个请求中从 HTTP header 中的 client-side 发送令牌?
我愿意接受有关如何在存储和发送 JWT 之间建立这种联系的建议(自 JWT 工作的生成和验证以来) 谢谢
是的,这样发送令牌就足够了。您只需要确保客户端以某种方式收到令牌。在您的特定情况下,客户端将向 /login
端点发送 POST 请求,并从对请求的响应中读取令牌。在 semi-pseudo 代码中 (client-side Javascript):
http.post('/login', (response) => {
let token = response.split(' ')[1];
});
客户端存储令牌。它存储在 localStorage, sessionStorage or in a cookie. There are pros and cons 中用于各种存储位置。必须对客户端进行编程以将其存储在其中一个位置,而服务器根本不存储它。如果您使用 front-end 框架(例如 Angular 或 React),您可以使用 Google 和搜索词(例如 "angular, jwt, storing")找到大量信息和示例。如果您使用的是普通 JS,则可以按照提供的 link 中的示例进行操作。基于上面的 semi-pseudo 代码:
http.post('/login', (response) => {
let token = response.split(' ')[1];
localStorage.setItem('token', token);
});
令牌与 HTTP header 中称为 Authorization 的每个请求一起发送。 header 应具有以下格式
Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
眼睛...东西是实际的令牌。在您的情况下,您可能必须使用 bearer (non-capitalized b),因为您已经将 Passport 设置为拥有它方法。您也可以在您的代码中将其设为 auth.authenticate('Bearer', ...
,使其更 "correct"。在较旧的文档和博客文章中,您经常可以看到 JWT 而不是 Bearer,但这并不真正遵循 de-facto 标准。
如果您以这种方式发送,Passport 应该可以正确读取令牌。
如何在客户端添加Authorization header取决于您是否使用框架,以及客户端是否是浏览器。如果你使用的是 vanilla JS,你可以阅读 this link。如果您使用的是框架,则可以 google "set authorization header, angular" 或类似的东西。官方文档和博客文章中通常都有大量信息。如果您使用的是 front-end 框架,则添加 Authorization 字段的代码部分通常称为 auth 拦截器。拦截器有点像中间件。
最后,你在写这个:
How should I store the token using a RestAPI...
REST 并不关心令牌的存储方式。它是在客户端完成的,与 REST 无关。但是,REST 关心端点的名称。如果 /login
是一个动词,它真的是正确的名字吗?问题被提出并得到回答 here.