Я пытаюсь реализовать конечную точку входа в систему с помощьюpassword.js. Моя пользовательская схема содержит псевдоним и пароль. Пока в app.js у меня есть:
require('./config/passport');
app.use('/user', passport.authenticate('jwt', {session: false}), require('./routes/user/login.js'));
Мне нужен мой файл паспорт.js, который имеет конфигурацию стратегии паспорта:
passport.use(new LocalStrategy({ usernameField: 'nickname' }, (nickname, password, done) => {
User.findOne({ nickname: nickname })
.then(user => {
if (!user) {
return done(null, false, { message: 'Email and/or password is not valid' });
}
bcrypt.compare(password, user.password, (err, isMatch) => {
if (err) throw err;
if (isMatch) {
return done(null, user);
} else {
return done(null, false, { message: 'Email and/or password is not valid' });
}
});
});
})
);
passport.use(new JWTStrategy({
jwtFromRequest: ExtractJWT.fromAuthHeaderAsBearerToken(),
secretOrKey: keys.secretJWT
},
function (jwtPayload, cb) {
return User.findOneById(jwtPayload.id)
.then(user => {
return cb(null, user);
})
.catch(err => {
return cb(err);
});
})
);
и в app.js (первый фрагмент) на /user
мне нужна фактическая конечная точка, которая:
router.post('/login', function (req, res, next) {
passport.authenticate('local', {session: false}, (err, user, info) => {
console.info(info);
if (err || !user) {
return res.status(400).json({
message: 'Email and/or password is not valid',
user: user
});
}
req.login(user, {session: false}, (err) => {
if (err) next(err);
//generate a signed JWT with the contents of user object and return it in the response
const token = jwt.sign(user, keys.secretJWT);
return res.json({user, token});
});
})(req, res);
});
поэтому в конце концов он вызывается при вызове /user/login
. Странно для меня то, что console.info(info);
на самом деле никогда не консоль, я не вижу его в терминале, в котором работает мое приложение node.
Я передаю действительный никнейм и пароль, но всегда получаю 401 Unauthorized:
Что мне не хватает? Может быть, это потому, что я не передаю токен? Но при входе в систему я не знаю токен. Это должно быть в ответ на вход в систему. И затем я буду аутентифицироваться с помощью токена при дальнейших запросах.
Я думаю, вам не хватает псевдонима вашей стратегии в функцииpassport.use(). Вы используете псевдоним jwt
в своем маршрутизаторе:
passport.authenticate('jwt', {session: false})
Итак, ваша функция паспорта.use() должна выглядеть так:
passport.use('local', new LocalStrategy(...), function(payload, cb){...})
passport.use('jwt', new JWTStrategy(...), function(payload, cb){...})
В противном случае вы не сможете сопоставить правильную стратегию с псевдонимом. Также в контроллере входа в систему вы должны вызывать паспорт с «локальным» псевдонимом в этом случае.