节点快速通行证 (JWT) - 身份验证后回调
Posted
技术标签:
【中文标题】节点快速通行证 (JWT) - 身份验证后回调【英文标题】:Node express passport (JWT) - callback after auth 【发布时间】:2016-12-25 08:30:01 【问题描述】:我使用护照 JWT 进行身份验证,但我在运行回调函数/响应时遇到困难,仅当用户通过身份验证。如何做到这一点?
在我的路线中:
import express from 'express';
import passport from '../../config/passport';
import memberInfoCtrl from '../controllers/memberInfo';
const router = express.Router();
router.route('/members')
.get(membersCtrl.tokenCheck, passport.authenticate('jwt', session: false ), membersCtrl.doSomethingElse);
export default router;
如果身份验证成功,我希望运行membersCtrl.doSomethingElse
。
这是我的 tokenCheck 函数:
function tokenCheck(req, res, next)
const token = getToken(req.headers);
if (token)
const decoded = jwt.decode(token, config.secret);
User.findOne(
email: decoded.email
, (err, user) =>
if (err) throw err;
if (!user)
return res.status(403).send(
success: false, msg: 'Authentication failed. User not found.'
);
// res.json( success: true, msg: 'Welcome to the member area!' );
return next();
);
else
return res.status(403).send( success: false, msg: 'No token provided.' );
在tokenCheck
中使用res.json
可以正常工作,但之后不会调用doSomethingElse
函数。
我以为是因为我们发送了这样的回复:
res.json( success: true, msg: 'Welcome to the member area!' );
将res.json
替换为return next();
会返回错误:
Error: Unknown authentication strategy \"jwt\"
为什么会发生这种情况 - 我如何在执行另一个功能之前检查身份验证,对于相同的路由?
我确定我错过了一些愚蠢的东西。任何帮助表示赞赏!
这是我初始化护照的主要快递脚本的一部分:
import passport from 'passport';
...
app.use(passport.initialize());
app.use('/api', routes);
...
护照配置:
const JwtStrategy = require('passport-jwt').Strategy;
import User from '../server/models/user';
import config from './env';
module.exports = (passport) =>
const opts = ;
opts.secretOrKey = config.secret;
passport.use(new JwtStrategy(opts, (jwtPayload, done) =>
User.findOne( id: jwtPayload.id , (err, user) =>
if (err)
return done(err, false);
if (user)
done(null, user);
else
done(null, false);
);
));
;
【问题讨论】:
没人能帮忙吗?我头疼:-) 【参考方案1】:您的一般方法是正确的。要根据某些条件保护路由,请编写自定义中间件调用next()
(如果满足这些条件)。
但在您的情况下,这不是必需的,因为这是 passport-jwt
所做的。所以假设你正确配置了passport
和passport-jwt
,你需要写的是这样的:
router.route('/members')
.get(passport.authenticate('jwt', session: false ), membersCtrl.doSomethingElse);
passport-jwt
将从请求中提取 JWT,并根据您提供的密钥或密钥对其进行验证。之后它将使用护照的verify
回调来填充req.user
(source)。
另外:是的,在使用 res.json()
后会发送响应,这就是在这种情况下无法访问您的护照中间件和其他任何内容的原因。
关于您的错误Error: Unknown authentication strategy \"jwt\"
:如果您没有正确配置护照身份验证,通常会发生这种情况。如果您将其包含在您的问题中,我将查看它并相应地扩展我的答案。
更新:您的代码对我来说看起来不错,除了一件事:您没有在 passport-jwt
选项中指定 jwtFromRequest
属性,这是强制性的。还是您忘记调用您的护照配置?
更新 2: 进一步澄清我在下面的评论: 1.) 在您的主要 express 脚本并调用它:
import passport from 'passport';
import passportConfig from 'path/to/passport/config';
...
app.use(passport.initialize());
passportConfig(passport);
...
2.) 确保删除您的 tokenCheck
函数,您不需要它。请参阅此答案的第一部分。
更新 3:“未经授权”非常棒,因为这意味着您现在成功地保护了您的 /members
路由。要实现基于令牌的身份验证,您现在需要一个额外的路由/authenticate
,用户可以在其中请求访问您的 Web 服务,例如通过提供凭据(您的路由将验证这些凭据并使用 JWT 进行响应,该 JWT 必须使用您用于 passport-jwt
的相同秘密进行签名 - 否则 passport-jwt
以后将无法验证令牌签名)。
但这超出了这个问题的范围。应该有很多资源可以涵盖这一点。例如,您可以使用jsonwebtoken
实现/authenticate
路由,该路由显示在this article 中(他们根本不使用passport
,而是使用jsonwebtoken
来创建令牌和验证)。
注意:如果您还要实现客户端,则必须在其中包含一些额外的逻辑来存储 JWT 并将其包含在您对 express 应用的请求中。
【讨论】:
谢谢乔纳斯,非常有帮助。我在我的问题中包含了更多细节。我有一个模块化的 ES6 方法。似乎护照没有在我的路由模块或其他东西中初始化,因为路由上调用了“未知策略”错误? 护照实例是作为单例实现的,因此使用passport
作为参数调用您的配置模块一次应该可以在应用程序范围内工作......
配置模块 - 护照配置是什么意思?我现在正在这样做:app.use(passport.initialize());
我已经加入了jwtFromRequest
,但同样的问题。仅当我在 tokenCheck
函数中将 res.json()
替换为 return next()
时,才会出现此问题。使用res.json
工作正常,但我需要在tokenCheck
之后运行中间件。
"之后它将使用护照的验证回调来填充 req.user"。那部分是黄金 :) 看起来很简单,但实际上 Passport 并没有很好地记录它。以上是关于节点快速通行证 (JWT) - 身份验证后回调的主要内容,如果未能解决你的问题,请参考以下文章
如何测试使用 JWT 身份验证的节点 API(使用用户登录获取令牌)
检索 JWT 身份验证的证书/密钥时出现问题。 (节点/Express/C#/IdentityServer)
使用节点 js、AngularJs 和 JWT 使用用户名和密码进行身份验证