[英]Node express passport (JWT) - callback after auth
I have authentication working with passport JWT, but I am having difficulty running a callback function/response, only if a user is authenticated. 我有使用护照JWT的身份验证,但是只有在用户通过身份验证后才能运行回调函数/响应。 How can this be done? 如何才能做到这一点?
In my routes: 在我的路线:
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;
I want membersCtrl.doSomethingElse
to be run if authentication is successful. 如果身份验证成功,我希望运行membersCtrl.doSomethingElse
。
Here is my tokenCheck function: 这是我的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.' });
}
}
Using res.json
in tokenCheck
works fine, but the doSomethingElse
function is not getting called afterwards. 在tokenCheck
使用res.json
工作正常,但之后不会调用doSomethingElse
函数。
I thought it's because we send a response like this: 我以为是因为我们发送了这样的回复:
res.json({ success: true, msg: 'Welcome to the member area!' });
Replacing the res.json
with return next();
用return next();
替换res.json
return next();
returns the error: 返回错误:
Error: Unknown authentication strategy \\"jwt\\"
Why does this happen - how can I check for authentication before executing another function, for the same route? 为什么会发生这种情况 - 如何在执行另一个功能之前检查相同路由的身份验证?
I'm sure it's something silly i'm missing. 我确定这是一件我很想念的傻事。 Any help is appreciated! 任何帮助表示赞赏!
Here is part of my main express script that initialises passport: 这是我的主要快递脚本的一部分,初始化护照:
import passport from 'passport';
...
app.use(passport.initialize());
app.use('/api', routes);
...
Passport config: 护照配置:
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);
}
});
}));
};
Your general approach is correct. 你的一般方法是正确的。 To protect a route depending on some conditions write a custom middleware calling next()
if those conditions are fulfilled. 要根据某些条件保护路由,请编写调用next()
的自定义中间件next()
如果满足这些条件next()
。
But in your case this is not necessary as this is what passport-jwt
does. 但在你的情况下,这不是必要的,因为这是passport-jwt
作用。 So assuming that you configured passport
and passport-jwt
correctly all you need to write is this: 所以假设您正确配置了passport
和passport-jwt
,您需要编写的是:
router.route('/members')
.get(passport.authenticate('jwt', { session: false }), membersCtrl.doSomethingElse);
passport-jwt
will extract the JWT from the request and verify it against your provided secret or key. passport-jwt
将从请求中提取JWT并根据您提供的秘密或密钥进行验证。 Afterwards it will use passport's verify
callback to populate req.user
( source ). 之后,它将使用passport的verify
回调来填充req.user
( 源 )。
Additionally: Yes after using res.json()
a response is sent which is why your passport middleware and anything beyond is not reached in that case. 另外:使用res.json()
后发送一个响应,这就是为什么你的护照中间件和其他任何东西都没有达到的原因。
Regarding your error Error: Unknown authentication strategy \\"jwt\\"
: This usually happens if you did not configure your passport authentication correctly. 关于您的错误Error: Unknown authentication strategy \\"jwt\\"
:如果您没有正确配置您的护照身份验证,通常会发生这种情况。 If you include it in your question I will take a look at it and extend my answer accordingly. 如果你把它包含在你的问题中,我会看一下并相应地扩展我的答案。
Update: Your code looks good to me except one thing: You did not specify the jwtFromRequest
attribute in your passport-jwt
options which is mandatory. 更新:您的代码看起来不错,除了一件事:您没有在passport-jwt
选项中指定jwtFromRequest
属性,这是强制性的。 Or did you by any chance forget to invoke your passport config? 或者你有没有机会忘记调用你的护照配置?
Update 2: Further clarification regarding my comment below: 更新2:关于我的评论的进一步说明如下:
1.) Import your ES6 passport config module ( where you added the jwtFromRequest
option ) in your main express script and invoke it: 1.)在主快捷脚本中导入您的ES6护照配置模块( 您在其中添加了jwtFromRequest
选项 )并调用它:
import passport from 'passport';
import passportConfig from 'path/to/passport/config';
...
app.use(passport.initialize());
passportConfig(passport);
...
2.) Make sure to remove your tokenCheck
function, you don't need it. 2.)确保删除tokenCheck
功能,您不需要它。 See the first part of this answer. 请参阅本答案的第一部分。
Update 3: 'Unauthorized' is great because it means that you are successfully protecting your /members
route now. 更新3: '未授权'很棒,因为这意味着您现在成功保护您的/members
路线。 To implement a token-based authentication you now need an additional route /authenticate
where users can request access to your web service eg by providing credentials (your route will verify these credentials and respond with a JWT which must be signed with the same secret you are using for passport-jwt
- otherwise passport-jwt
will not be able to verify the token signature later). 要实现基于令牌的身份验证,您现在需要一个额外的路由/authenticate
,用户可以请求访问您的Web服务,例如通过提供凭据(您的路由将验证这些凭据并使用JWT进行响应,必须使用相同的秘密进行签名)用于passport-jwt
- 否则passport-jwt
将无法在以后验证令牌签名。
But this goes beyond the scope of this question. 但这超出了这个问题的范围。 There should be many resources out there covering this. 应该有很多资源可以解决这个问题。 You can for example implement an /authenticate
route using jsonwebtoken
which is shown in this article (they are not using passport
at all but use jsonwebtoken
for token creation and validation). 例如,您可以实施/authenticate
中使用路由jsonwebtoken
这是在显示这篇文章 (他们没有用passport
都而是用jsonwebtoken
令牌创建和验证)。
Note: If you are also implementing a client you have to include some additional logic there to store the JWT and to include it in your requests to the express app. 注意:如果您还要实现客户端,则必须在其中包含一些额外的逻辑来存储JWT并将其包含在您对Express应用程序的请求中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.