• node+vue前后端分离实现登录时使用图片验证码


    记录一下前端使用验证码登录的过程
    后端用的是node.js,关键模块是svg-captcha
    前端使用的是vue2
    最后的登录界面如下:
    在这里插入图片描述

    后端代码

    先上代码,然后解释

    const svgCaptcha = require('svg-captcha')
    
    exports.checkCode = (req, res) => {
        const img = svgCaptcha.create({
            size: 4,
            ignoreChars: '0o1l',
            color: true,
            noise: 1,
            background: '#666',
            height: 40,
            width: 113
        })
        console.log(img.text);
        res.send(img)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    这是最关键的代码,我习惯将路由和路由处理函数分开写,上面这块代码是路由处理函数
    实际上就是利用svg-captcha生成了一个验证码图片,其中有几个参数需要重点关注一下:

    • height和width,这个是设置的验证码的高度和宽度,需要看一下前端页面上input输入框的高度和宽度,我用的是elementUI,高度是40,所以这里的高度也是40,宽度自己慢慢调
    • ignoreChars:验证码中不出现这些字符
      看一下路由代码:
    const express = require('express');
    const userHandle = require('../route_handle/user')
    
    const router = express.Router();
    
    router.get('/checkCode', userHandle.checkCode)
    
    module.exports = router
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    这没啥好说的
    后端就这些了,后端的端口用的是3020,需要设置一下跨域,不然前端访问不到

    前端代码

    先上代码

    <template>
      <div class="login">
        <el-form class="login-form" :model="loginForm">
          <h3 class="title">若依后台管理系统</h3>
          <el-form-item>
            <el-input placeholder="Account" type="text" prefix-icon="el-icon-user-solid" v-model="loginForm.username">
            </el-input>
          </el-form-item>
          <el-form-item>
            <el-input placeholder="Password" type="password" prefix-icon="el-icon-lock" v-model="loginForm.password">
            </el-input>
          </el-form-item>
          <el-form-item>
            <el-input placeholder="CheckCode" prefix-icon="el-icon-picture-outline-round" v-model="loginForm.checkCode"
              style="width: 63%">
            </el-input>
            <div class="login-code">
              <!-- <img :src="codeUrl" class="login-code-imgs" @click="getCode"/> 
              -->
              <div @click="getCode" v-html="code" style="vertical-align:middle"></div>
            </div>
          </el-form-item>
          <el-checkbox v-model="loginForm.rememberme" style="margin: 0 0 15px 0;">Remenber Me</el-checkbox>
          <el-form-item>
            <el-button style="width: 100%" @click="submit('loginForm')" type="primary">Login</el-button>
          </el-form-item>
        </el-form>
        <div class="el-login-footer">
          <span>Copyright © 2018-2022 huanggang All Rights Reserved.</span>
        </div>
      </div>
    </template>
    
    <script>
    // import { getCodeImg } from '@/api/login'
    export default {
      data() {
        return {
          loginForm: {
            username: '',
            password: '',
            checkCode: '',
            rememberme: false
          },
          codeUrl: '',
          code: '',
          codeText: ''
        }
      },
      methods: {
        submit() {
          if (this.loginForm.checkCode.toLowerCase() == this.codeText.toLowerCase()) {
            this.$message({
              type: "success",
              message: '登录成功'
            })
          } else (this.$message({
            type: 'error',
            message: '验证码错误!'
          }))
        },
        getCode() {
          this.$axios.get('/checkCode')
            .then(res => {
              console.log(res)
              this.code = res.data.data
              this.codeText = res.data.text
            })
        }
      },
      created() {
        this.getCode()
      }
    }
    </script>
    
    <style scoped lang="scss">
    .login {
      display: flex;
      height: 100%;
      background: url(../assets/images/login-background.jpg);
      background-size: cover;
      justify-content: center;
      align-items: center;
    }
    
    .title {
      text-align: center;
      color: #707070;
      margin: 0 auto 30px;
    }
    
    .login-form {
      box-sizing: border-box;
      width: 400px;
      border-radius: 6px;
      background-color: #fff;
      padding: 25px 25px 5px 25px;
    }
    
    .el-login-footer {
      height: 40px;
      line-height: 40px;
      position: fixed;
      bottom: 0;
      color: #fff;
      font-size: 12px;
      letter-spacing: 1px;
      font-family: Arial;
    }
    
    .login-code {
      width: 33%;
      float: right;
    
      div {
        cursor: pointer;
      }
    }
    
    .login-code-imgs {}
    </style>
    
    
    • 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
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123

    这里不再赘述相关的配置了,直接看关键代码

    获取验证码方法

    getCode() 方法实现的功能是点击验证码图片时,切换获取验证码
    获取验证码的方法是访问后端接口/checkCode,这个接口返回两个值(后端补充说明),一个是text,一个是data,text就是验证码的字符串值,data是验证码的html地址,在postman中测试返回的结果如下:

    在这里插入图片描述
    页面上使用v-html绑定验证码显示的地址
    然后把text和data的值都赋给相应的数据
    当然,为了能打开登录页面时,直接能显示验证码图片,需要把getCode方法挂载在生命周期函数created上

    登录验证方法

    登录验证不再校验数据库中的用户名和密码,只示意一下验证码的功能
    在点击login按钮时校验验证码是否正确,功能写在submit()方法中,前端input框中使用v-model双向绑定了loginForm.checkCode的值,所以只要验证loginForm.checkCode与验证码codeText是否相等即可,为了保证用户体验,一般是忽略字母输入大小写的,所以都使用toLowerCase()处理一下。
    这样就完成了前后端分离模式的登录验证码使用功能

  • 相关阅读:
    Imagery in Action | Week6 影像服务
    TCP为什么需要3次握手?
    重生奇迹MU装备好坏如何判断
    好的架构是进化来的,不是设计来的
    浏览器播放rtsp视频,基于nodeJs
    分组后取最大值对应记录
    1.Spring的简单使用
    这是什么代码帮我看看
    从零开始 Spring Boot 26:AOP
    MVC4自带的JS、CSS优化功能
  • 原文地址:https://blog.csdn.net/u012848304/article/details/127663984