如何设置PassportJS进行后端身份验证?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何设置PassportJS进行后端身份验证?相关的知识,希望对你有一定的参考价值。
因此,在连续60个小时搜索互联网之后,我决定在SO上发布一个问题。
目前我正在尝试构建一个React应用程序。它的结构是这样的,在/client
下是所有反应代码(在localhost:3000
)和/server
处理除了认证之外的所有api
请求(在localhost:5000
)。 (使用MERN堆栈)
现在我真的在努力让PassportJS工作。我已经仔细阅读了这里提供的文档:http://www.passportjs.org/docs/以及使用此处提供的本地策略的示例:https://github.com/passport/express-4.x-local-example/blob/master/server.js
我现在的问题是初始身份验证(带有凭据的POST
请求)很顺利。但是,我相信serializeUser
并没有将user.id
中的session
序列化(但绝对被称为!)。当输出req.session
时,我得到:
Session {
cookie:
{ path: '/',
_expires: null,
originalMaxAge: null,
httpOnly: true,
secure: false } }
然而,似乎有些东西确实有效,因为如果我查看req.sessionStore.sessions
,我会看到与user.id
的饼干:
{ 'mxsYcA2DrYVz4E5q-BiBbw8_810Slj-2':
'{"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"},
"passport":{"user":"5c93f9a655f8a740f732a9c1"}}',
'hW_cvQeJLk7JpLxK7TZVzIMuOEMi6-6w':
'{"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"},
"passport":{"user":"5c93f9a655f8a740f732a9c1"}}',
'7_2AWWdijpVVl6OFrmauorBt1Q4crBGa':
'{"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"},
"passport":{"user":"5c93f9a655f8a740f732a9c1"}}'
}
除非服务器重新启动,否则这些cookie似乎会在页面刷新期间保留。
我不确定要提供什么代码,但我可以在必要时添加其他代码段。
passport.js
var mongoose = require('mongoose');
var User = mongoose.model('User');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
function verifyPassword(user, password) {
return (user.password == password);
}
passport.use(new LocalStrategy(
function(username, password, done) {
User.findOne({ username: username }, function (err, user) {
if (err) {
return done(err);
} else if (!user) {
return done(null, false);
} else if (!verifyPassword(user, password)) {
return done(null, false);
} else {
return done(null, user);
}
});
}
));
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
AuthRoutes.js
var passport = require('passport');
module.exports = function(app) {
app.post('/auth', passport.authenticate('local', {
successRedirect: '/success',
failureRedirect: '/invalid'
}));
app.get('/auth', passport.authenticate('local', {
successRedirect: '/success',
failureRedirect: '/invalid'
}));
app.get('/success', function(req, res) {
console.log('success');
console.log(req.session);
res.sendStatus(200);
});
app.get('/invalid', function(req, res) {
console.log('invalid');
console.log(req.session);
res.sendStatus(403);
});
app.get('/logout', function(req, res) {
req.logout();
});
};
server.js
const express = require('express');
const process = require('process');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const session = require('express-session');
const passport = require('passport');
const cors = require('cors');
const app = express();
// Prevents CORS issues
app.use(cors());
// Decides Port
const port = process.env.PORT || 5000;
// MongoDB
const User = require('./api/models/UserModel');
const db_name = "testdb";
mongoose.Promise = global.Promise;
mongoose.connect(process.env.MONGODB_URI+"/"+db_name);
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(session({
secret: 'this_is_my_secret_salt',
resave: false,
saveUninitialized: true,
cookie: {secure: true}
}));
require("./config/passport");
app.use(passport.initialize());
app.use(passport.session());
// Add Auth Routes
var authRoutes = require('./api/routes/AuthRoutes');
authRoutes(app);
// console.log that your server is up and running
app.listen(port, () => console.log(`Listening on port ${port}`));
我知道这不是最可重复的代码,但任何帮助或建议都将非常感激。我可以编辑问题,使其更容易访问!
编辑1
所以我现在能够在会话中获得user.id
。我这样做是通过将我的cors
声明更改为app.use(cors({credentials: true, origin: 'http://localhost:3000'}));
然后提供POST
和GET
请求的凭据。不幸的是,即使存在user
,我仍然没有获得认证。
编辑2
我已在上面的代码中更正了deserializeUser
函数
我不知道你错过了什么但是这个护照配置代码在最近的项目中对我有用:
app.js
中的Passport配置:
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const User = require('./models/User');
// Passport configuration
app.use(
require('express-session')({
cookie: { maxAge: 43200000 },
secret: 'secret',
resave: false,
saveUninitialized: true
})
);
app.use(passport.initialize());
app.use(passport.session());
passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
User.js
中的用户模型:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const passportLocalMongoose = require('passport-local-mongoose');
const User = new Schema({
username: {
type: String,
required: true
},
password: {
type: String,
required: true
},
isAdmin: {
type: Boolean,
default: false
}
});
User.plugin(passportLocalMongoose);
module.exports = mongoose.model('User', User);
认证路线:
// @route POST /register
// @desc Register new user
// @access Public
router.post('/register', (req, res) => {
const newUser = new User({
username: req.body.username
});
User.register(newUser, req.body.password, (err, user) => {
if (err) {
res.redirect('/register'); //failure redirect
}
passport.authenticate('local')(req, res, () => {
res.redirect('/programs'); //success redirect
});
});
});
// @route POST /login
// @desc
// @access Public
router.post(
'/login',
passport.authenticate('local', {
successRedirect: '/programs',
failureRedirect: '/login'
})
);
希望这会有所帮助,问候。
以上是关于如何设置PassportJS进行后端身份验证?的主要内容,如果未能解决你的问题,请参考以下文章
javascript PassportJS身份验证设置#passportjs #cookiesession #nodejs
如果用户通过一次身份验证,防止用户再次登录passportjs?
Express Passportjs在路由器回调中未进行身份验证