节点快递护照(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了passportpassport-jwt ,你需要写的是:

 router.route('/members') .get(passport.authenticate('jwt', { session: false }), membersCtrl.doSomethingElse); 

passport-jwt将从请求中提取JWT,并根据您提供的密钥或密钥对其进行validation。 之后,它将使用护照的verifycallback来填充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来创buildvalidation令牌)。

注意:如果您还在实施客户端,则必须在其中包含一些额外的逻辑来存储JWT,并将其包含在对快速应用程序的请求中。