一、简介
如果需要了解 express
和 passport
自行百度了解。
本项目主要使用了以下技术node
+ express
+ postgreSQL
+ sequelize
+ passport
如果不了解前四项
请先查看 nodejs + express + postgreSQL + sequelize 该文章
二、需要引入的插件
npm install passport passport-local express-session
三、配置passport
app.js
添加
const session = require('express-session')
app.use(session({
secret:'test',
cookie:{httpOnly:true,secure: false ,maxAge:30*24*60*60*1000}, // 保存30天
// secure: true 需要HTTPS,如果是http则不会设置cookie
resave: false,
saveUninitialized: false
}))
// passport配置
require('./config/passport')(app)
创建文件passport.js
const User = require('../control/user')
const passport = require('passport')
const LocalStrategy = require('passport-local').Strategy
module.exports = function(app){
// 初始化
app.use(passport.initialize())
app.use(passport.session())
var isValidPassword = function (user, password) {
return user.password == password
}
// 在调用req.logIn()后执行该方法,将用户的user.js保存到session中
passport.serializeUser(function(user, done) {
done(null, user.id);
})
passport.deserializeUser(function(id, done) {
User.queryUserById(id).then((user) => {
done(null, user);
}).catch((err) => {
done(err);
})
})
// 进行登录认证
passport.use('login', new LocalStrategy({
usernameField: 'username',
passwordField: 'password',
// 根据表单key值的不同进行修改 默认为username,password
passReqToCallback: true
// passReqToCallback: true, 将req参数添加到回调用使用
}, function (req, username, password, done) {
// 查询用户数据
User.queryUserByName(username).then((user) => {
if(!user){
return done(null, false, {
error: '用户名不存在'
})
}else if(!isValidPassword(user, password)){
return done(null, false, {
error: '密码错误!'
})
}else{
return done(null, user)
}
}).catch((err) => {
return done(null, false, err)
})
}))
// 如果有多种登录方式,可以继续通过passport.user()添加
}
四、在登录中的路由中进行认证
routes/login.js
const express = require('express')
const router = express.Router()
const login = require('../control/login')
router.post('/', (req, res, next) => {
login(req).then((msg) => {
res.send(msg)
}).catch((err) => {
res.send(err)
})
})
module.exports = router
control/login.js
认证方法调用
const passport = require('passport')
module.exports = function (req){
return new Promise((resolve, reject) => {
// 认证
passport.authenticate('login', function(err, user, info){
if(err || !user){ // 判断是否认证成功
reject(info)
}else{
// 调用此方法后将用户登录数据保存到session中
req.logIn(user, function(err){
if(err){
reject({message: '认证失败'})
}else{
// 删除用户数据中的密码
delete user.dataValues['password']
resolve(user)
}
})
}
})(req)
})
}
五、查询用户信息
routes/user.js
const express = require('express')
const router = express.Router()
const User = require('../control/user')
// 认证,如果登录req.isAuthenticated() 为ture,否则为false
var isAuthenticated = function(req, res, next) {
if (req.isAuthenticated()) {
return next();
} else {
res.status(401).json({
error: 'Unauthorized!'
});
return;
}
}
// 先进行认证判断,在执行回调
router.get('/', isAuthenticated, (req, res) => {
User.queryUserAll().then((user) => {
res.json(user)
}).catch((err) => {
res.send(err)
})
})
module.exports = router
control/user.js
查询用户信息的各种方法
const {User} = require('../models/index')
module.exports = {
queryUserAll(){
return new Promise((resolve, reject) => {
User.findAll().then((res) => {
resolve(res)
}).catch((err) => {
console.log(err)
reject(err)
});
})
},
queryUserById(id){
return new Promise((resolve, reject) => {
User.findAll({
where: {
id: id
}
}).then((res) => {
resolve(res)
}).catch((err) => {
console.log(err)
reject(err)
});
})
},
queryUserByName(username){
return new Promise((resolve, reject) => {
User.findOne({
where: {
username: username
}
}).then((res) => {
resolve(res)
}).catch((err) => {
console.log(err)
reject(err)
});
})
},
}
六、退出登录
routes/logout.js
const express = require('express')
const router = express.Router()
router.get('/', (req, res, next) => {
req.session.destroy() // 销毁session
req.logOut() // 退出登录
res.json({message: '退出登录'})
})
module.exports = router