Joe*_*Tea 0 javascript jwt passport.js
我的问题的关键是PassportJS 似乎正在验证 JWT,当当前时间超过 exp 参数时,该 JWT 应该是无效的。
我已经提供了相关的代码片段以及我认为应该发生的事情的解释(尽管显然不是!!)
// In server.js
// ...
const passport = require("passport");
// ...
require("./config/passport")(passport);
app.use(passport.initialize());
// ...
Run Code Online (Sandbox Code Playgroud)
// In token.js (used to issue JWT)
const jsonwebtoken = require("jsonwebtoken");
// ...
const issueJWT = (user) => {
const _id = user._id;
const expiresIn = 30000; // 30s for testing purposes
const payload = {
sub: _id,
iat: Date.now(),
};
const signedToken = jsonwebtoken.sign(payload, PRIV_KEY, {
expiresIn: expiresIn,
algorithm: "RS256",
});
return {
token: "Bearer " + signedToken,
expires: expiresIn,
};
};
Run Code Online (Sandbox Code Playgroud)
// In passport.js
const JwtStrategy = require("passport-jwt").Strategy;
const ExtractJwt = require("passport-jwt").ExtractJwt;
// ...
const options = {
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: PUB_KEY,
algorithms: ["RS256"],
};
module.exports = (passport) => {
passport.use(
new JwtStrategy(options, (jwt_payload, done) => {
User.findOne({ _id: jwt_payload.sub }, (err, user) => {
if (err) {
return done(err, false);
}
if (user) {
return done(null, user);
} else {
return done(null, false);
}
});
})
);
};
Run Code Online (Sandbox Code Playgroud)
// In routes.js
// ...
const passport = require("passport");
const { authenticateWithAccessToken } = require("../controllers/usersController");
// ...
router
.route("/authenticate-with-access-token")
.get(
passport.authenticate("jwt", { session: false }),
authenticateWithAccessToken
);
Run Code Online (Sandbox Code Playgroud)
// In usersController.js
exports.authenticateWithAccessToken = async (req, res, next) => {
try {
const user = req.user;
res.status(200).json({
success: true,
name: user.name,
email: user.email,
});
} catch (err) {
next(err);
}
};
Run Code Online (Sandbox Code Playgroud)
{
alg: "RS256",
typ: "JWT"
}.
{
sub: "5eec9f1c4a416c1e50fc0a8e", // user._id
iat: 1593258411458, // 2020-06-27 11:46:51
exp: 1593258441458 // 2020-06-27 11:47:21
}.
[signature]
Run Code Online (Sandbox Code Playgroud)
jsonwebtoken.verify()
)尝试验证 JWT,但发现Date.now()
超过了 JWT 的到期时间next()
我确信我错过了一些明显的事情,但我一生都无法弄清楚发生了什么。感谢您提前提供任何帮助!
好吧,我想通了!
事实证明(通过查看 jsonwebtoken 文档上的示例),签署令牌时使用的 iat 属性应该以秒为单位,而不是毫秒。因此Date.now()
tokens.js 中的内容实际上应该是Math.floor(Date.now / 1000)
:
// In token.js (used to issue JWT)
const jsonwebtoken = require("jsonwebtoken");
// ...
const issueJWT = (user) => {
const _id = user._id;
const expiresIn = 30; // 30s for testing purposes
const payload = {
sub: _id,
iat: Math.floor(Date.now() / 1000),
};
const signedToken = jsonwebtoken.sign(payload, PRIV_KEY, {
expiresIn: expiresIn,
algorithm: "RS256",
});
return {
token: "Bearer " + signedToken,
expires: expiresIn,
};
};
Run Code Online (Sandbox Code Playgroud)