• Koa全栈登录鉴权


    鉴权、加密、HTTPS概念

    登录鉴权流程

    在这里插入图片描述

    鉴权

    • 基础鉴权
    • session/cookie
    • JWT
    • Oauth等

    算法加密

    算法中的指令描述的是一个计算,当其运行时能从一个初始状态和初始输入(可能为空)开始,经过一系系列有限而清晰定义的状态最终产生输出并停止于一个终态。

    数据加密的基本过程,就是对原来为明文的文件或数据按某种算法进行处理,使其成为不可读的一段代码,通常称为“密文”。通过这样的途径,来达到保护数据不被非法人窃取、阅读的目的。

    • Base64
    • MD5
    • SHA-1
    • DES
    • AES
    • RSA
    • ECC等

    HTTPS

    HTTPS (HyperText Transfer Protocol Secure)
    本传输安全协议,常称为HTTP over TLS、HTTP over
    SSLHTTP Secure)是一种通过计算机网络进行安全通
    信的传输协议。

    • SSL
    • HTTP劫持
    • 数据篡改
    • 敏感信息
    • 中间人等

    常见的鉴权方式及优缺点

    Session/cookie

    • 优点
      • 较易拓展,简单
    • 缺点
      • 安全性低
      • 性能低,服务端储存
      • 多服务同步session困难
      • 跨平台困难

    JWT

    • 优点
      • 易扩展
      • 支持移动设备
      • 跨应用调用
      • 安全
      • 承载信息丰富
    • 缺点
      • 刷新与过期处理
      • Payload不易过大
      • 中间人攻击

    Oauth

    • 优点

      • 开放
      • 安全(QQ微信扫码等)
      • 简单
      • 权限指定(登录第三方,授权界面)
    • 缺点

      • 需要增加授权服务器
      • 增加网络请求

    使用JWT方式开发登录鉴权模块

    登录流程

    集成JWT

    • 安装
    npm i -S koa-jwt
    
    • 1
    • 使用

      • 登录接口接口实现,在密码验证码通过时使用JWT生成token返回给前端
    • 登录接口

    import jsonwebtoken from 'jsonwebtoken'
      async login (ctx) {
        // 验证用户账户密码是否正确
        // 返回token
        // 1.接受用户数据
       const {body} = ctx.request
       const {sid, code, username, password} = body
       console.log(sid, code, username)
       // 2.验证图片验证码的时效性、正确性
      if (checkCode(sid, code)) {
        // 3.验证用户账户密码是否正确
        let checkUserPassword = false
        // mongoDB查库
        const user = await UserModel.findOne({username: username})
        console.log(user)
        // bcrypt保存密码的时候用的是这个加密的,比较也需要用bcrypt
        if (user.username === username && await bcrypt.compare(password, user.password)) {
          checkUserPassword = true
        }
        if (checkUserPassword) {
        // 4.验证通过返回token
          const token = jsonwebtoken.sign({id: 'zhangsan'}, config.JWT_SECRET, {
            expiresIn: '1d'
           })
            ctx.body = {
              token,
              code: 200,
              msg: '登录成功'
            }
        } else {
          // 用户 密码验证失败,返回提示
          ctx.body = {
            code: 404,
            msg: '用户名或密码错误'
          }
        }
      } else {
        ctx.body = {
          code: 401,
          msg: '图片验证码不正确'
        }
      }
      
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 注册接口
     async reg (ctx) {
       
        // 1.接受客户端的数据
        const { body } = ctx.request 
        const {code, username, password, name, sid } = body
        console.log('code, username, password, name, sid', code, username, password, name, sid)
        // 2.校验验证码的内容(时效性、有效性)
        if (checkCode(sid, code)) {
          // 3.查库,看username是否被注册
          let check = true
          const userDB_username = await UserModel.findOne({username: username})
          console.log('userDB_username', userDB_username)
          if (userDB_username && typeof userDB_username.username !== 'undefined') {
            check = false
            ctx.body = {
              code: 401,
              msg: '该邮箱已注册,可以通过邮箱找回密码'
            }
          }
          const userDB_name = await UserModel.findOne({name: name})
          // 4.查库,看name是否被注册
          if( userDB_username && typeof userDB_name.name !== 'undefined') {
            check = false
            ctx.body = {
              code: 401,
              msg: '该昵称已存在!'
            }
          }
          // 5.写入数据到数据库
          if (check) {
            let pwd = await bcrypt.hash(password, 5)
            let user = new UserModel({
              username,
              name,
              password: pwd,
              created: moment().format('YYYY-MM-DD HH:mm:ss')
            })
            let result = await user.save()
            ctx.body = {
              code: 200,
              data: result,
              msg: '注冊成功'
            }
          }
        } else {
          ctx.body = {
            code: 401,
            msg: '图片验证码不正确'
          }
        }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    总结

    • 前端sid唯一标识使用的是uuid
    • 验证码的时效使用的是redis
    • 密码保存加密使用的是bcrypt
      在这里插入图片描述
  • 相关阅读:
    Termux Api
    【校招VIP】产品思维考察之创意能力
    几个可以整蛊你朋友的Python程序
    【动态规划】96. 不同的二叉搜索树
    rust宏
    C Primer Plus(6) 中文版 第10章 数组和指针 10.6 保护数组中的数据
    信我,ThreadPoolExecutor经典面试问题就在这~
    【Linux】ss 命令使用详解
    关联通达信自动化交易接口的代码分享
    【push,pop,shift,unshift】手写数组push,pop,shift,unshiftt方法
  • 原文地址:https://blog.csdn.net/weixin_44757417/article/details/126919830