护照验证 jwt 没有响应
Passport authenticate jwt not responding
我有一个基本的 MERN login/signup 应用程序,其中包含一条虚拟保护路由,仅对登录用户可见。我已经设置了与登录和注册相关的所有内容。
我在 cookie 中从服务器发送 jwt 令牌。到目前为止,aprt 工作正常。我可以注册,也可以登录。
但是当我对 /protected
路由进行 GET 调用时,passport.jwt
似乎不起作用。那里什么也没有发生。
这是我的 passport.js
配置:
import {Strategy} from 'passport-jwt';
// import {ExtractJwt} from 'passport-jwt';
import passport from 'passport';
import mongoose from 'mongoose';
import {UserSchema} from '../models/userModel';
import {config} from './config';
const User = mongoose.model('User', UserSchema);
const cookieExtractor = (req) => {
let token = null;
if(req && req.cookies) {
token = req.cookies['jwt'];
}
return token;
}
export const passportConfig = (passport) => {
const opts = {};
opts.jwtFromRequest = cookieExtractor;
opts.secretOrKey = config.key;
passport.use(
new Strategy(opts, (jwt_payload, done) => {
User.findById(jwt_payload.id)
.then((user) => {
if(user) {
return done(null, user);
}
return done(null, false);
})
.catch((err) => {
console.log('Error in finding user by id in jwt.');
});
})
);
};
这里是 userRoutes.js
:
import { addNewUser, loginUser, verifyLogin } from '../controllers/userController';
export const routes = (app) => {
app.route('/users/register')
.post(addNewUser);
app.route('/users/login')
.post(loginUser);
app.route('/users/protected')
.get(verifyLogin);
}
最后,这是我 userController.js
中的 verifyLogin
和 loginUser
控制器:
export const loginUser = (req, res) => {
console.log(req.body);
if(mongoSanitize.has(req.body)) {
return res.send(400).json({error: "Characters $ and . are prohibited. Use different values."});
}
const {errors, isValid} = validateLoginInput(req.body);
if(!isValid) {
return res.status(400).json(errors);
}
const userName = req.body.userName;
const password = req.body.password;
User.findOne({userName: userName})
.then((user) => {
if(!user) {
return res.status(404).json({userNotFound: "Username not found."});
}
else {
bcrypt.compare(password, user.password)
.then((isMatch) => {
if(isMatch) {
const payload = {
id: user.id,
name: user.fullName
};
const token = jwt.sign(payload, config.key, {expiresIn: 60});
res.cookie('jwt', token, {httpOnly: true, secure: false});
res.status(200).json({success: true, token: token});
}
else {
return res.status(400).json({incorrectPassword: "Password incorrect."});
}
})
}
});
};
export const verifyLogin = () => {
console.log('protected'); //'protected' is printed
passport.authenticate('jwt', {session: false}),
(req, res) => {
console.log('here'); //'here' is not printed
const { user } = req;
res.send(200).send({user});
};
};
控制器 loginUser
工作正常,我可以看到响应中的令牌,而且我还有一个包含 jwt key:value 对的 cookie。
但是第三个控制器 verifyLogin
在 passport.authenticate
调用后没有做任何事情。
有什么地方我可能做错了什么吗?
好的,所以我能够修复。其他人有同样的问题,问题是我没有使用 passport.authenticate
作为中间件,而是我将它作为一个函数调用,并在成功验证时进行回调。以下是我所做的更改:
userRoutes.js
:
export const routes = (app) => {
app.route('/register')
.post(addNewUser);
app.route('/login')
.post(loginUser);
app.route('/protected')
.get(passport.authenticate('jwt', {session:false}), verifyLogin);
}
然后verifyLogin
只是将登录的用户信息发回:
export const verifyLogin = (req, res) => {
console.log('here');
const { user } = req;
res.status(200).json({message:'Secure route', user: user});
};
其他都差不多。
在我将时间更改为 1 小时之前,我遇到了同样的问题。看起来你写的值是以毫秒为单位的,所以你应该写 60000
.
而不是 60
我有一个基本的 MERN login/signup 应用程序,其中包含一条虚拟保护路由,仅对登录用户可见。我已经设置了与登录和注册相关的所有内容。
我在 cookie 中从服务器发送 jwt 令牌。到目前为止,aprt 工作正常。我可以注册,也可以登录。
但是当我对 /protected
路由进行 GET 调用时,passport.jwt
似乎不起作用。那里什么也没有发生。
这是我的 passport.js
配置:
import {Strategy} from 'passport-jwt';
// import {ExtractJwt} from 'passport-jwt';
import passport from 'passport';
import mongoose from 'mongoose';
import {UserSchema} from '../models/userModel';
import {config} from './config';
const User = mongoose.model('User', UserSchema);
const cookieExtractor = (req) => {
let token = null;
if(req && req.cookies) {
token = req.cookies['jwt'];
}
return token;
}
export const passportConfig = (passport) => {
const opts = {};
opts.jwtFromRequest = cookieExtractor;
opts.secretOrKey = config.key;
passport.use(
new Strategy(opts, (jwt_payload, done) => {
User.findById(jwt_payload.id)
.then((user) => {
if(user) {
return done(null, user);
}
return done(null, false);
})
.catch((err) => {
console.log('Error in finding user by id in jwt.');
});
})
);
};
这里是 userRoutes.js
:
import { addNewUser, loginUser, verifyLogin } from '../controllers/userController';
export const routes = (app) => {
app.route('/users/register')
.post(addNewUser);
app.route('/users/login')
.post(loginUser);
app.route('/users/protected')
.get(verifyLogin);
}
最后,这是我 userController.js
中的 verifyLogin
和 loginUser
控制器:
export const loginUser = (req, res) => {
console.log(req.body);
if(mongoSanitize.has(req.body)) {
return res.send(400).json({error: "Characters $ and . are prohibited. Use different values."});
}
const {errors, isValid} = validateLoginInput(req.body);
if(!isValid) {
return res.status(400).json(errors);
}
const userName = req.body.userName;
const password = req.body.password;
User.findOne({userName: userName})
.then((user) => {
if(!user) {
return res.status(404).json({userNotFound: "Username not found."});
}
else {
bcrypt.compare(password, user.password)
.then((isMatch) => {
if(isMatch) {
const payload = {
id: user.id,
name: user.fullName
};
const token = jwt.sign(payload, config.key, {expiresIn: 60});
res.cookie('jwt', token, {httpOnly: true, secure: false});
res.status(200).json({success: true, token: token});
}
else {
return res.status(400).json({incorrectPassword: "Password incorrect."});
}
})
}
});
};
export const verifyLogin = () => {
console.log('protected'); //'protected' is printed
passport.authenticate('jwt', {session: false}),
(req, res) => {
console.log('here'); //'here' is not printed
const { user } = req;
res.send(200).send({user});
};
};
控制器 loginUser
工作正常,我可以看到响应中的令牌,而且我还有一个包含 jwt key:value 对的 cookie。
但是第三个控制器 verifyLogin
在 passport.authenticate
调用后没有做任何事情。
有什么地方我可能做错了什么吗?
好的,所以我能够修复。其他人有同样的问题,问题是我没有使用 passport.authenticate
作为中间件,而是我将它作为一个函数调用,并在成功验证时进行回调。以下是我所做的更改:
userRoutes.js
:
export const routes = (app) => {
app.route('/register')
.post(addNewUser);
app.route('/login')
.post(loginUser);
app.route('/protected')
.get(passport.authenticate('jwt', {session:false}), verifyLogin);
}
然后verifyLogin
只是将登录的用户信息发回:
export const verifyLogin = (req, res) => {
console.log('here');
const { user } = req;
res.status(200).json({message:'Secure route', user: user});
};
其他都差不多。
在我将时间更改为 1 小时之前,我遇到了同样的问题。看起来你写的值是以毫秒为单位的,所以你应该写 60000
.
60