图片验证码的实现

开发环境 :vue + asp.net core

验证码的实现过程

实现过程说明:

后台生成验证码,以图片的形式返回前端,但不传相应的生成验证码的字母及数字组合,
前台接收后台返回的FileConentResult型数据流文件,通过img接收,自动转化为图片展示在前台。
方法一:(个人未实现该方法)由于前后端分离,会存在跨域的问题,前台必须向后台传递cookie值或者一个唯一的id值,
才能保证后台以session形式获取对应值,即HttpContext.Session.SetString("ver",4位验证码)该方法不安全
方法二:故改为以下形式避免跨域问题,且安全
以token的形式进行登录人验证码的存储,登录成功后自动删除token验证码,仅保证在后端传输,不会明文出现在前台,避免暴力破解的可能。

具体实现如下:

1、首先,后台引用nuget包文件zkweb.system.drawing.4.0.1.nupkg
1.1如果是外网的开发环境,可直接搜索并引用nuget包文件。
1.2离线情况下,先到官网下载指定文件后,导入内网开发环境后,

步骤如下:

1、工具=》nuget包管理器=》程序包管理器设置=》程序包源=》如果nuget.org勾选,则取消勾选=》右上角加号=》名称:自定义M 源:选定官网下载的nupkg文件=>确定
2、工具=》nuget包管理器=》管理解决方案的nuget程序包=》浏览=》点击刚才定义名称M=>再点击右侧的安装,等待完成即可
2、后台生成几位验证码,几条干扰线,随机的字体颜色及随机的字体然后形成图片的长宽高(自定义)

   [Route("CreateVer")]
   [HttpGet]
   public FileContentResult CreateVer()
   {
		int codeW = 80;
		int codeH = 30;
		int fontSize = 16; 
		Random rnd= new Random();
		//颜色列表,用于验证码、噪线、噪点
		Color[] color = { Color.Black, Color.Red, Color.Blue, Color.Green, Color.Orange, Color.Brown, Color.Brown, Color.DarkBlue };
		//字体列表,用于验证码
		string[] font = { "Times New Roman" };
		//验证码的字符集,去掉了一些容易混淆的字符

		//写入Session、验证码加密
		//WebHelper.WriteSession("session_verifycode", Md5Helper.MD5(chkCode.ToLower(), 16));
		//创建画布
		Bitmap bmp = new Bitmap(codeW, codeH);
		Graphics g= Graphics.FromImage(bmp);
		g.Clear(Color.White);
		//画噪线
		for (int i = 0; i < 2; i++)
		{
		   int x1 = rnd.Next(codeW);
		   int y1 = rnd.Next(codeH);
		   int x2 = rnd.Next(codeW);
		   int y2 = rnd.Next(codeH);
			Color clr= color[rnd.Next(color.Length)];
			g.DrawLine(new Pen(clr), x1, y1, x2, y2);
		}//合法随机显示字符列表
		  string strLetters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
		  StringBuilder s = new StringBuilder();
		//画验证码字符串
		for (int i = 0; i < 4; i++)//4代表生成4位验证码
		{
			s.Append(strLetters.Substring(r.Next(0, strLetters.Length - 1), 1));
		    string fnt = font[rnd.Next(font.Length)];
			Font ft= new Font(fnt, fontSize);
			Color clr= color[rnd.Next(color.Length)];
			g.DrawString(s[s.Length - 1].ToString(), ft, new SolidBrush(clr),(float)i * 18, (float)0);
		}
		//将验证码图片写入内存流,并将其以 "image/Png" 格式输出
		MemoryStream ms = new MemoryStream();
		try
		{
			bmp.Save(ms, ImageFormat.Png);
			/*重点   此处存于后台自定义实体的token中,以便点击登录按钮时候进行验证*/
			VerifyCodeService.Configure(s.toString());/*这个是token的启动配置,必须有*/
			VerifyCode vermodel = new VerifyCode();
			vermodel.loginSurever = s.toString();
			var vertoken = jwtVerifyCodeHelper.IssueJwt(vermodel,_appSetting);//_appSetting为该登录机器的而唯一标识
			
		   return File(ms.ToArray(),@"image/Png");
		}
		catch (Exception)
		{
		   return null;
		}
		finally
		{
			g.Dispose();
			bmp.Dispose();
		}   
   }

前台vue接收文件File

           布局略 
          <el-form-item prop="ver">
            <el-row :span = "24">
              <el-col :span="12"> 
                <el-input
                  v-model="form.loginver"
                  placeholder="请输入验证码"
                  hide-required-asterisk="false"
                  maxlength="6"                  
                ></el-input>
              </el-col>
              <el-col :span="12">
                <img id="verimg" :src="imgcode"  @click="refresh()">
              </el-col>
            </el-row>
          </el-form-item>
		  布局略
  data() {
    return {
      form: {
        userCode: "",
        password: "",
        loginver:"",//输入验证码的值
      },
      imgcode:this.$api.getRoot() + '/api/Login/CreateVer' //请求后台获取验证码赋值给img
    };
  },
  methods: {
    refresh: function()//点击验证码刷新验证码
    {
      var num = Math.ceil(Math.random()*10);
      this.imgcode = this.$api.getRoot() + '/api/Login/CreateVer?' + num;//防止缓存影响验证码的刷新
    }
	handleLogin: function(logincontinue) {//点击登录按钮时候的验证,如果验证码错误,自动再次向后端请求验证码,刷新前台验证码
	_this.$api.post(url, param, response => {	
		if (response.code == 500) {
			if (response.message.indexOf("验证码错误") > -1) {
					 _this.refresh();//刷新验证码
					 _this.form.loginver = "";//清空验证码的输入框
				}
		}
	});
	}
  }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值