node+passport+express进行登录认证 (part 1)

一、简介

如果需要了解 expresspassport 自行百度了解。
本项目主要使用了以下技术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

git地址

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容