express实现管理后台校验登录

express实现管理后台校验登录

声明

笔者是一名应届前端技术小白,由于公司的项目需求有幸当一回全栈工程师。这篇文章是对管理后台登录功能的拆解教程,部分参考了前辈的博客,写下这篇文章权当是学习笔记和经验积累。欢迎学习交流,喷子绕道。


http协议属于无状态协议,无法记录上一次的会话信息。但实际业务场景中,我们的需求往往是一次登录成功以后对管理员进行记忆,下次登录时无须再输入用户名和密码。为了保证安全性,存储进入数据库的密码应当是加密过后的哈希值。
当客户端通过表单post提交账号密码过来的时候,后台获取到http请求中body的密码,通过加密算法后进行哈希值比对来验证登录成功与否。

npm安装所需依赖

cnpm i express-session --save
cnpm i  bcryptjs

操作Mongodb时采用的是mongoose,你应当在user.js里面配置数据库集合的约束条件,采用导出的model来操作数据库。

var mongoose = require('mongoose');
// 定义集合约束条件
var Schema = mongoose.Schema;
var userRuleSchema = new Schema({
    "userName": { type: String, required: true, index: { unique: true } },
    "password": { type: String, required: true }
});

敏感数据存储进入数据库时必须先对其加密,采用bcrypt来加密。以下代码来自于前端乱炖站长的博客: 传送门

var bcrypt = require('bcryptjs');
var SALT_WORK_FACTOR = 10;
userRuleSchema.pre('save', function (next) {
    var user = this;
    if (!user.isModified('password')) return next();    //产生密码hash当密码有更改的时候(或者是新密码)
    bcrypt.genSalt(SALT_WORK_FACTOR, function(err, salt) {
        if (err) return next(err);
         //  结合salt产生新的hash
        bcrypt.hash(user.password, salt, function(err, hash) {
            if (err) return next(err);
            // 使用hash覆盖明文密码
            user.password = hash;
            next();
        });
    });
})

链接数据库来测试我们存储进入mongodb的密码是否为hash值

 // db.js
 var  users = require('./models/user');
 var mongoose = require('mongoose');
 mongoose.connect('mongoodb://127.0.0.1:27017/fashion'); 
 mongoose.connection.on('connected',function(){
    console.log('MongoDB connected success');
 })   
var testUser = new users({
    userName:'wuquan',
    password:'haha123'
 });
 testUser.save(function(err){
  if(!err){
    console.log('存储成功');
  }   
 })

如果按照以上代码来的话,此时在mongodb上面的密码应当是加密的hash值了。我们还应当在user.js里面写一个方法来进行密码哈希值比对

//  密码比对方法
userRuleSchema.methods.comparePassword = function(candidatePassword, cb) {
    bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
        if (err) return cb(err);
        cb(null, isMatch);
    });
};
module.exports = mongoose.model('user',userRuleSchema);

万事俱备,此时只要接受来自于客户端的用户名和密码,查询数据库进行比对就可以了。

var express = require('express');
var router = express.Router();
var users = require('../models/user');
router.post('/login', function (req, res, next) {
  var userName = req.body.userName;
  var password = req.body.pass;
  users.findOne({ userName: userName }, function (err, user) {       // 查询数据库 
    if (err) {
      res.json({
        status: '0',
        msg: '用户名不存在',
        result: ''
      })
    } else {
      user.comparePassword(password, function (err, isMatch) {
        if (err) {
          res.json({
            status: '0',
            msg: err.message,
            result: ''
          })
        }
        if ((password, isMatch) == true) {     // 用户名和密码正确
          res.json({
            status: '1',
            msg: '登录成功',
            result: ''
          });
          // 此处还应当写入session
        } else {
          res.json({
            status: '0',
            msg: '用户名或者密码错误',
            result: ''
          })
        }
      })
    }
  });

以上是管理后台的账号密码登录校验过程,当登录成功时,我们还应当写入一个session字段返回给客户端,以便于下次客户端进行访问时可以直接跳过登录。

先对session进行配置

// app.js
var express = require('express');
var app = express();
var session = require('express-session');
app.use( 
 session({
   secret:'secret',              //  用来对session_id相关的cookie进行签名
   resave:false,                      
   saveUninitialized: false,     
   cookie: {userName:"default",maxAge: 7*24*60*60*1000}    // 设置有效期
  })
)

登录成功时写入session

// 当用户名和密码都正确时
req.session.userName = userName;
req.session.isLogin = true;

有些页面我们允许无需登录就可以访问,有些页面我们需要拦截并强制要求其登录。由于项目采用前后端分离,重定向部分交由前端的vue-router来实现。

app.use(function (req, res, next) {     // 下次登录时验证session
  if (req.session.userName) {
    next();
      } else {             // 未登陆时拦截部分页面请求
    if (req.originalUrl == '/fashion') {      // 需要将路由拦截部分写在路由规则前面,否则会先跳转到对应的页面去了
      res.json({
        status: '0',
        msg: '当前尚未登录',
        result: ''
      })
    } else {
      next();
    }
  }
});

参考博客链接:
基于Mongoose和bcrypt的密码验证
Nodejs使用session、cookie进行登录验证功能的实现

你可能感兴趣的:(Node.js)