节点快递护照(JWT) – auth后callback
我有authentication工作与护照智威汤逊,但我有困难运行callback函数/响应, 只有当用户通过身份validation。 如何才能做到这一点?
在我的路线:
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;
如果authentication成功,我想要membersCtrl.doSomethingElse
运行。
这是我的tokenCheckfunction:
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!' });
用return next();
replaceres.json
return next();
返回错误:
Error: Unknown authentication strategy \"jwt\"
为什么会发生这种情况 – 在执行另一个函数之前,如何在同一条path上检查身份validation?
我确定这是我很想念的东西。 任何帮助表示赞赏!
这是我的护照初始化的主要expression脚本的一部分:
import passport from 'passport'; ... app.use(passport.initialize()); app.use('/api', routes); ...
护照configuration:
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); } }); })); };
您的一般方法是正确的。 要根据某些条件保护路由,如果满足这些条件,则编写一个自定义中间件,调用next()
。
但在你的情况下,这不是必要的,因为这是passport-jwt
所做的。 所以假设你正确地configuration了passport
和passport-jwt
,你需要写的是:
router.route('/members') .get(passport.authenticate('jwt', { session: false }), membersCtrl.doSomethingElse);
passport-jwt
将从请求中提取JWT,并根据您提供的密钥或密钥对其进行validation。 之后,它将使用护照的verify
callback来填充req.user
( 来源 )。
另外:是的,在使用res.json()
之后,发送了一个响应,这就是为什么你的护照中间件和其他任何东西都没有达到的情况。
关于您的错误Error: Unknown authentication strategy \"jwt\"
:如果您没有正确configuration您的通行证身份validation,通常会发生这种情况。 如果你把它包括在你的问题中,我会看看它,并相应地扩大我的答案。
更新:你的代码看起来不错,除了一件事情:你没有在你的passport-jwt
选项中指定jwtFromRequest
属性。 或者你有没有机会忘记调用你的护照configuration?
更新2:关于我的评论进一步澄清下面:
1.)在你的主express脚本中导入你的ES6护照configuration模块( 在你添加了jwtFromRequest
选项的地方 )并调用它:
import passport from 'passport'; import passportConfig from 'path/to/passport/config'; ... app.use(passport.initialize()); passportConfig(passport); ...
2.)确保删除你的tokenCheck
函数,你不需要它。 看到这个答案的第一部分。
更新3: “未经授权”是伟大的,因为这意味着你现在成功地保护你的/members
路线。 要实现基于令牌的身份validation,您现在需要一个额外的路由/authenticate
,用户可以请求访问您的Web服务,例如通过提供凭据(您的路由将validation这些凭据并与JWT进行响应,必须使用与您相同的密码使用passport-jwt
– 否则passport-jwt
将无法在稍后validation令牌签名)。
但这超出了这个问题的范围。 这里应该有很多资源。 你可以例如使用jsonwebtoken
中展示的jsonwebtoken
实现/authenticate
路由(他们根本不使用passport
,而是使用jsonwebtoken
来创build和validation令牌)。
注意:如果您还在实施客户端,则必须在其中包含一些额外的逻辑来存储JWT,并将其包含在对快速应用程序的请求中。