Passport JWT req.user 在我的一条路线中未定义
Passport JWT req.user is undefined in one of my routes
试图用我的 Express 应用程序设置 JWT 真是一场噩梦!我想我现在已经基本正常工作了,我有一个注册路由和登录路由,它们都可以正常工作并生成有效的令牌,我的“/用户”路由中有另一个路由,我用它来测试身份验证,这一切都很好。但是我有另一个文件包含 '/api' 的路由,这是身份验证实际上很重要的地方,我有一个类似的测试路由试图访问 req.user (就像我在其他路由中所做的那样)但似乎 req.user 未定义。通过一些调试,用户似乎在 req.account 中,这很奇怪,我不明白为什么它不在 req.user
中
我在 /config/passport.js
中定义了我的 jwt 策略
'use strict';
const User = require('../models/user'),
config = require('./main'),
JwtStrategy = require('passport-jwt').Strategy,
ExtractJwt = require('passport-jwt').ExtractJwt;
//exported to be used by passport in server set up
module.exports = function (passport) {
const jwtOptions = {
// Telling Passport to check authorization headers for JWT
jwtFromRequest: ExtractJwt.fromAuthHeader(),
// Telling Passport where to find the secret
secretOrKey: config.secret
};
const jwtLogin = new JwtStrategy(jwtOptions, function(payload, done) {
User.findById(payload._id, function(err, user) {
if (err) { return done(err, false); }
if (user) {
done(null, user);
} else {
done(null, false);
}
});
});
passport.use(jwtLogin);
}
护照作为参数传递给它,然后在主 express 文件中初始化
这是 /users 路由文件,可以正常工作。使用授权 header 和 'JWT ' 向 /users/isAuth 发送 GET 请求工作正常,我的用户名发回给我
"use strict";
const express = require('express'),
router = express.Router(),
jwt = require('jsonwebtoken'),
User = require('../models/user'),
config = require('../config/main'),
passport = require ('passport');
function generateToken(user) {
return jwt.sign({_id: user._id}, config.secret, {
expiresIn: 10080
});
}
.
. Here are routes for login and register they perform as expected
. and work fine
.
/* ==================================
Test Authentication Route
================================== */
router.get('/isAuth', passport.authenticate('jwt', { session: false }), function(req, res) {
console.log(req.user);
res.json({username: req.user.username});
});
module.exports = router;
虽然在这个文件中,对于 api 发送请求到 GET /api/testAuth 的路由与以前完全相同,使用相同的令牌和相同的 headers 我没有回来req.user 并且在控制台中我看到 req.user 未定义。但是在控制台中似乎确实有用户 object 就像 req.account 一样?我不明白这里发生了什么,希望有人能提供帮助!
"use strict";
const express = require('express'),
router = express.Router(),
jwt = require('jsonwebtoken'),
Server = require('../models/server'),
passport = require('passport');
// Test route to see if logged in user is matt
router.get('/testAuth', passport.authorize('jwt', { session: false }), function(req, res) {
console.log(req.user);
if (req.user) {
if(req.user.username == "matt") {
res.send("You are matt!");
} else {
res.send("You are not matt!");
}
} else {
res.send("no req.user");
}
})
module.exports = router;
您在 testAuth 路由中使用了 passport.authorize
,这适用于已经登录并具有会话信息的用户。由于您没有使用会话存储,因此您没有持久的 req.user
对象,因此应该在所有路由
上使用 passport.authenticate
req.user
对象仅在您使用使用会话的护照身份验证策略时设置。在这种情况下,身份验证是无状态的,因为您指定了 {session: false}
,这对于 api 应该是这样的。因此,会话没有用户对象。以下是我在 passport.authenticate
中间件中设置 req.user
对象的方法:
修改您的 jwtOptions
以允许将请求对象传递给 JwtStrategy
函数:
const jwtOptions = {
// Telling Passport to check authorization headers for JWT
jwtFromRequest: ExtractJwt.fromAuthHeader(),
// Telling Passport where to find the secret
secretOrKey: config.secret,
passReqToCallback: true, //<= Important, so that the verify function can accept the req param ie verify(req,payload,done)
};
修改 JwtStrategy 的参数,将请求对象作为第一个参数;然后在 if (user)
块中,只需将返回的用户对象分配给 req.user
:
const jwtLogin = new JwtStrategy(jwtOptions, function(req, payload, done) {
User.findById(payload._id, function(err, user) {
if (err) { return done(err, false); }
if (user) {
req.user = user; // <= Add this line
done(null, user);
} else {
done(null, false);
}
});
});
就是这样:现在任何具有 passport.authenticate("jwt", {session: false})
中间件的路由都将在成功验证后收到 req.user
。
试图用我的 Express 应用程序设置 JWT 真是一场噩梦!我想我现在已经基本正常工作了,我有一个注册路由和登录路由,它们都可以正常工作并生成有效的令牌,我的“/用户”路由中有另一个路由,我用它来测试身份验证,这一切都很好。但是我有另一个文件包含 '/api' 的路由,这是身份验证实际上很重要的地方,我有一个类似的测试路由试图访问 req.user (就像我在其他路由中所做的那样)但似乎 req.user 未定义。通过一些调试,用户似乎在 req.account 中,这很奇怪,我不明白为什么它不在 req.user
中我在 /config/passport.js
中定义了我的 jwt 策略'use strict';
const User = require('../models/user'),
config = require('./main'),
JwtStrategy = require('passport-jwt').Strategy,
ExtractJwt = require('passport-jwt').ExtractJwt;
//exported to be used by passport in server set up
module.exports = function (passport) {
const jwtOptions = {
// Telling Passport to check authorization headers for JWT
jwtFromRequest: ExtractJwt.fromAuthHeader(),
// Telling Passport where to find the secret
secretOrKey: config.secret
};
const jwtLogin = new JwtStrategy(jwtOptions, function(payload, done) {
User.findById(payload._id, function(err, user) {
if (err) { return done(err, false); }
if (user) {
done(null, user);
} else {
done(null, false);
}
});
});
passport.use(jwtLogin);
}
护照作为参数传递给它,然后在主 express 文件中初始化
这是 /users 路由文件,可以正常工作。使用授权 header 和 'JWT ' 向 /users/isAuth 发送 GET 请求工作正常,我的用户名发回给我
"use strict";
const express = require('express'),
router = express.Router(),
jwt = require('jsonwebtoken'),
User = require('../models/user'),
config = require('../config/main'),
passport = require ('passport');
function generateToken(user) {
return jwt.sign({_id: user._id}, config.secret, {
expiresIn: 10080
});
}
.
. Here are routes for login and register they perform as expected
. and work fine
.
/* ==================================
Test Authentication Route
================================== */
router.get('/isAuth', passport.authenticate('jwt', { session: false }), function(req, res) {
console.log(req.user);
res.json({username: req.user.username});
});
module.exports = router;
虽然在这个文件中,对于 api 发送请求到 GET /api/testAuth 的路由与以前完全相同,使用相同的令牌和相同的 headers 我没有回来req.user 并且在控制台中我看到 req.user 未定义。但是在控制台中似乎确实有用户 object 就像 req.account 一样?我不明白这里发生了什么,希望有人能提供帮助!
"use strict";
const express = require('express'),
router = express.Router(),
jwt = require('jsonwebtoken'),
Server = require('../models/server'),
passport = require('passport');
// Test route to see if logged in user is matt
router.get('/testAuth', passport.authorize('jwt', { session: false }), function(req, res) {
console.log(req.user);
if (req.user) {
if(req.user.username == "matt") {
res.send("You are matt!");
} else {
res.send("You are not matt!");
}
} else {
res.send("no req.user");
}
})
module.exports = router;
您在 testAuth 路由中使用了 passport.authorize
,这适用于已经登录并具有会话信息的用户。由于您没有使用会话存储,因此您没有持久的 req.user
对象,因此应该在所有路由
passport.authenticate
req.user
对象仅在您使用使用会话的护照身份验证策略时设置。在这种情况下,身份验证是无状态的,因为您指定了 {session: false}
,这对于 api 应该是这样的。因此,会话没有用户对象。以下是我在 passport.authenticate
中间件中设置 req.user
对象的方法:
修改您的
jwtOptions
以允许将请求对象传递给JwtStrategy
函数:const jwtOptions = { // Telling Passport to check authorization headers for JWT jwtFromRequest: ExtractJwt.fromAuthHeader(), // Telling Passport where to find the secret secretOrKey: config.secret, passReqToCallback: true, //<= Important, so that the verify function can accept the req param ie verify(req,payload,done) };
修改 JwtStrategy 的参数,将请求对象作为第一个参数;然后在
if (user)
块中,只需将返回的用户对象分配给req.user
:const jwtLogin = new JwtStrategy(jwtOptions, function(req, payload, done) { User.findById(payload._id, function(err, user) { if (err) { return done(err, false); } if (user) { req.user = user; // <= Add this line done(null, user); } else { done(null, false); } }); });
就是这样:现在任何具有 passport.authenticate("jwt", {session: false})
中间件的路由都将在成功验证后收到 req.user
。