node后台登录和注册

  1. 创建数据表(Users)
    sequelize model:generate --name User --attributes username:string,password:string,openid:string,admin:boolean
    sequelize db:migrate    #运行迁移
  2. 创建一个 users.js的 文件
    image
  3. 下载jsonwebtoken:      jwt(json web token)网络通行令牌,有了这个令牌,能够在Restful风格的代码中识别用户信息
    https://www.npmjs.com/package/jsonwebtoken
    cnpm install jsonwebtoken –S
  4. 在 users.js里引入 var jwt = require('jsonwebtoken');并且配置登录(未完善)的接口代码:

  5. var express = require('express');
    var router = express.Router();
    var models = require('../../models')
    var jwt = require('jsonwebtoken');// 加密
    
    router.post('/login', function(req, res, next) {
      var username = req.body.username
      var password = req.body.password
    
      if(!username || !password){
        res.json({success:false,message:'用户名或密码错误'})
        return;
      }
    
      models.User.findOne({
        where:{
          username:username,
          password:password
        }
      }).then(user=>{
        if(!user){
          res.json({success:false,message:'用户名或者密码错误!'})
        }
        // 使用jwt 加密当前的用户输入的信息,并且秘钥加 盐
        var token = jwt.sign({user:user},'0429');
        res.json({
          success:true,
          message:'请求成功',
          token:token
        })
      })
    });
    
    module.exports = router;
  6. 在数据库 添加一个 用户:
    image
    然后测试一个 登录接口:
    image
    此时登录密码,在数据库是明文, 所以还不完善;只是作为测试登录

  7. 配置 app.js ,在app.js中加上中间件, 只要  请求头里 携带 token 才能访问页面:(node的导航守卫,配置没带token就不能访问页面)

  8. app.use(function(req, res, next) {
      // 6.不需要验证就可以访问的页面(注册页面,登录页面)
       var allowUrl = ['/admin/users/login','/admiin/users/register','/users/login']
        if(allowUrl.indexOf(req.url) != '-1') return next()// 如果访问的页面在allowUrl数组里,就允许访问
      // 1.验证token是否存在
       var token;
       // 如果用户请求头携带了token  并且  token前面 带有 Bearer
       if(req.headers.authorization && req.headers.authorization.split(' ')[0]==='Bearer'){
         token = req.headers.authorization.split(' ')[1]
       }else if(req.query.token){
         token = req.query.token;
       }
       // 2.如果token不存在,
       if(!token){
         return res.status(401).send({
           success:false,
           message:'当前接口需要认证才能访问'
         })
       }
       // 3.先解密token,然后判断token是否正确;
       // verify解密    decoded是解密后的信息(也就是被加密的信息)
       jwt.verify(token,'0429',function(err,decoded){
          if(err){
            return res.status(401).send({
              suceess:false,
              messag:'token过期,请重新登录'
            })
          }
          // res.json(decoded) 返回解密后的信息
    
        // 4.验证是否是后台管理员
        var reg = /\admin/
        if(reg.test(req.url) && !decoded.user.admin){
          return res.status(401).send({
            success:false,
            message:"当前接口是管理员接口"
          })
        }
        //5. 解析出来的数据存入req
        req.decoed = decoded;
        next()// next()  功能就是 运行下一个函数
       })
    });
  9. 测试:
             没有带请求头 token 访问接口
    image
            带有请求头  token 访问接口
    image
              请求头 带上 错误的 token
    image
  10. 解析当前加密的信息:
    res.json(decoded)  可以返回当前解密后的 信息
    image

     注册:

  1. 由于目前密码在数据表中存的是明文的,不安全,所以在用户注册的时候就需要对密码进行加密处理
    https://www.npmjs.com/package/bcryptjs
    cnpm install bcryptjs –S  安装加密包
  2. 在 users.js的 文件 引入包:
  3. var bcrypt = require('bcryptjs');// 加密
  4. 并且配置登录的接口代码:
  5. // users.js
    var bcrypt = require('bcryptjs');// 加密
    // 注册
    router.post('/register',function(req,res,next){
      var username = req.body.username
      var password = req.body.password
      var check_password = req.body.check_password
      // 1.判断用户名密码是否为空
      if(!req.body.username || !req.body.password){
        res.json({succes:false,message:'用户名或密码必填'})
        return
      }
      // 2.判断两次密码是不是一致
      if(check_password != password){
        res.json({success:false,message:'两次输入的密码不一致'})
      }
     // 3.查找用户名是否被注册
      models.User.findOne({
        where:{
          username:username
        }
      }).then(user=>{
        if(user){// 已存在用户名
          res.json({success:false,message:'用户名已注册'})
          return
        }
        
        // 用户名不存在, 就在数据库添加这个注册信息
          password = bcrypt.hashSync(password,8)// 加密当前注册的密码,并且进行重新赋值
          models.User.create({
            username:username,
            password:password,// 此时的password已经被加密过
            admin:true
          }).then((user)=>{
            res.json({
              success:true,
              message:'请求成功',
              user:user
            })
          })
      })
    })
  6. 测试:
             成功注册
    image
    image
    image
  7. 但是有一个问题存在  , 由于注册的时候把密码 加密 存到了数据库
    如果用户登录 就会登录不上, 因为 此时的密码已经被 加密存在数据库了
    image
    image
  8. 用户登录的时候 , 通过解密对比 用户输入的 和 数据库被加密的  是否一致
    此时就要修改一下 登录的代码:

    完善登录代码:

  9. // 登录
    router.post('/login', function(req, res, next) {
      var username = req.body.username
      var password = req.body.password
      if(!username || !password){
        res.json({success:false,message:'用户名或密码错误'})
        return;
      }
      models.User.findOne({
        where:{
          username:username,
        }
      }).then((user)=>{
        if(!user) return res.json({success:false,message:'用户名不存在'})
        // 如果用户输入的密码和数据库加密的一致,就返回true
          if(!bcrypt.compareSync(password,user.password)){
            res.json({success:false,message:'密码错误!'})
            return;
          }
        // 使用jwt 加密当前的用户输入的信息,并且秘钥加 盐
        var token = jwt.sign({
          user:{
            username:username,
            admin:true // 返回为管理员用户
          }
        },process.env.SECRET,{expiresIn:60 * 60 * 24 * 7 });
        res.json({
          success:true,
          message:'登陆成功',
          token:token
        })
      })
    });
  10. 动态的 控制 盐:
    7.1   npm install dotenv -S
            Dotenv是一个零依赖模块,可将环境变量从.env文件加载到process.env中

    7.2   在项目根目录: 创建一个 .env的文件, 并且配置如下代码:
           SECRET=0429        // SECRET:后面是你要设置的 盐 
          
    7.3 打开users.js文件 和 app.js文件, 分别引入:
           require("dotenv").config();

         然后把两个文件需要用到 盐 的地方改成:
          process.env.SECRET

    image
posted @ 2020-06-18 19:40  飞鸟和蝉-  阅读(385)  评论(0编辑  收藏  举报