图形验证码+短信验证码实战

这篇具有很好参考价值的文章主要介绍了图形验证码+短信验证码实战。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言:

  上一篇分分享了基于阿里云实现的短信验证码文章,考虑到为了防止登录时,非人工操作,频繁获取验证码,趁热打铁,现在添加了图片验证码服务功能。借鉴网上传统的做法,把实现这两个验证的功能做成有个独立的服务,通过Http分别请求获取校验图片验证码和短信验证码。

一、需求描述:

  • 图形验证码为,短信验证码为6位纯数字
  • 同一系统图片验证码缓存中只存在一个,没有有效期,每次刷新更新旧图形验证码
  • 短信验证码有效期2分钟
  • 每个手机号60秒内只能发送一次短信验证码,在服务器端执行校验
  • 同一个手机号在同一时间内可以有多个有效的短信验证码,根据不同系统类型区分
  • 每个短信验证码至多可被使用3次,无论和请求中的验证码是否匹配,随后立即作废,以防止暴力攻击
  • 发送短信验证码之前,先验证图形验证码是否正确

二、图片验证码实现:

生成随机验证码字符串:

 /// <summary>
        /// 获取随机验证码
        /// </summary>
        /// <returns></returns>
        public static string GenerateCaptchaCode()
        {
            Random rand = new Random();
            int maxRand = Letters.Length - 1;

            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < 4; i++)
            {
                int index = rand.Next(maxRand);
                sb.Append(Letters[index]);
            }

            return sb.ToString();
        }

随机验证码生成验证码图片:

 /// <summary>
        /// 生成随机验证码图片
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="captchaCode"></param>
        /// <returns></returns>
        public static CaptchaResult GenerateCaptcha(int width, int height, string captchaCode)
        {
            using (Bitmap baseMap = new Bitmap(width, height))
            using (Graphics graph = Graphics.FromImage(baseMap))
            {
                Random rand = new Random();

                graph.Clear(GetRandomLightColor());

                DrawCaptchaCode();
                DrawDisorderLine();
                AdjustRippleEffect();

                MemoryStream ms = new MemoryStream();

                baseMap.Save(ms, ImageFormat.Png);

                return new CaptchaResult { CaptchaCode = captchaCode, CaptchaByteData = ms.ToArray(), Timestamp = DateTime.Now };

                int GetFontSize(int imageWidth, int captchCodeCount)
                {
                    var averageSize = imageWidth / captchCodeCount;

                    return Convert.ToInt32(averageSize);
                }

                Color GetRandomDeepColor()
                {
                    int redlow = 160, greenLow = 100, blueLow = 160;
                    return Color.FromArgb(rand.Next(redlow), rand.Next(greenLow), rand.Next(blueLow));
                }

                Color GetRandomLightColor()
                {
                    int low = 180, high = 255;

                    int nRend = rand.Next(high) % (high - low) + low;
                    int nGreen = rand.Next(high) % (high - low) + low;
                    int nBlue = rand.Next(high) % (high - low) + low;

                    return Color.FromArgb(nRend, nGreen, nBlue);
                }

                void DrawCaptchaCode()
                {
                    SolidBrush fontBrush = new SolidBrush(Color.Black);
                    int fontSize = GetFontSize(width, captchaCode.Length);
                    Font font = new Font(FontFamily.GenericSerif, fontSize, FontStyle.Bold, GraphicsUnit.Pixel);
                    for (int i = 0; i < captchaCode.Length; i++)
                    {
                        fontBrush.Color = GetRandomDeepColor();

                        int shiftPx = fontSize / 6;

                        //float x = i * fontSize + rand.Next(-shiftPx, shiftPx) + rand.Next(-shiftPx, shiftPx);
                        float x = i * fontSize + rand.Next(-shiftPx, shiftPx) / 2;
                        //int maxY = height - fontSize;
                        int maxY = height - fontSize * 2;
                        if (maxY < 0)
                        {
                            maxY = 0;
                        }
                        float y = rand.Next(0, maxY);

                        graph.DrawString(captchaCode[i].ToString(), font, fontBrush, x, y);
                    }
                }

                void DrawDisorderLine()
                {
                    Pen linePen = new Pen(new SolidBrush(Color.Black), 2);
                    //for (int i = 0; i < rand.Next(3, 5); i++)
                    for (int i = 0; i < 2; i++)
                    {
                        linePen.Color = GetRandomDeepColor();

                        Point startPoint = new Point(rand.Next(0, width), rand.Next(0, height));
                        Point endPoint = new Point(rand.Next(0, width), rand.Next(0, height));
                        graph.DrawLine(linePen, startPoint, endPoint);

                        //Point bezierPoint1 = new Point(rand.Next(0, width), rand.Next(0, height));
                        //Point bezierPoint2 = new Point(rand.Next(0, width), rand.Next(0, height));

                        //graph.DrawBezier(linePen, startPoint, bezierPoint1, bezierPoint2, endPoint);
                    }
                }

                void AdjustRippleEffect()
                {
                    short nWave = 6;
                    int nWidth = baseMap.Width;
                    int nHeight = baseMap.Height;

                    Point[,] pt = new Point[nWidth, nHeight];

                    for (int x = 0; x < nWidth; ++x)
                    {
                        for (int y = 0; y < nHeight; ++y)
                        {
                            var xo = nWave * Math.Sin(2.0 * 3.1415 * y / 128.0);
                            var yo = nWave * Math.Cos(2.0 * 3.1415 * x / 128.0);

                            var newX = x + xo;
                            var newY = y + yo;

                            if (newX > 0 && newX < nWidth)
                            {
                                pt[x, y].X = (int)newX;
                            }
                            else
                            {
                                pt[x, y].X = 0;
                            }


                            if (newY > 0 && newY < nHeight)
                            {
                                pt[x, y].Y = (int)newY;
                            }
                            else
                            {
                                pt[x, y].Y = 0;
                            }
                        }
                    }

                    Bitmap bSrc = (Bitmap)baseMap.Clone();

                    BitmapData bitmapData = baseMap.LockBits(new Rectangle(0, 0, baseMap.Width, baseMap.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
                    BitmapData bmSrc = bSrc.LockBits(new Rectangle(0, 0, bSrc.Width, bSrc.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

                    int scanline = bitmapData.Stride;

                    IntPtr scan0 = bitmapData.Scan0;
                    IntPtr srcScan0 = bmSrc.Scan0;

                    unsafe
                    {
                        byte* p = (byte*)(void*)scan0;
                        byte* pSrc = (byte*)(void*)srcScan0;

                        int nOffset = bitmapData.Stride - baseMap.Width * 3;

                        for (int y = 0; y < nHeight; ++y)
                        {
                            for (int x = 0; x < nWidth; ++x)
                            {
                                var xOffset = pt[x, y].X;
                                var yOffset = pt[x, y].Y;

                                if (yOffset >= 0 && yOffset < nHeight && xOffset >= 0 && xOffset < nWidth)
                                {
                                    if (pSrc != null)
                                    {
                                        p[0] = pSrc[yOffset * scanline + xOffset * 3];
                                        p[1] = pSrc[yOffset * scanline + xOffset * 3 + 1];
                                        p[2] = pSrc[yOffset * scanline + xOffset * 3 + 2];
                                    }
                                }

                                p += 3;
                            }
                            p += nOffset;
                        }
                    }

                    baseMap.UnlockBits(bitmapData);
                    bSrc.UnlockBits(bmSrc);
                    bSrc.Dispose();
                }
            }
        }

三、短信验证码实现:

见上篇:

传送门:基于Aliyun短信验证码实现

四、图片验证码获取与校验:

获取:

代码:

  /// <summary>
        /// 获取图片验证码
        /// </summary>
        /// <param name="imgCaptchaDto">图形验证码请求信息</param>
        [HttpGet("img")]
        public IActionResult GetImageCaptcha([FromQuery]ImgCaptchaDto imgCaptchaDto)
        {
            var result = _captchaService.GetImageCaptcha(imgCaptchaDto);
            var stream = new MemoryStream(result.CaptchaByteData);

            return new FileStreamResult(stream, "image/png");
        }

Http调用:详细调用参数和方式见下方接口在线文档。
图形验证码+短信验证码实战

校验:

代码:

 /// <summary>
        /// 验证图片验证码
        /// </summary>
        /// <param name="imgCaptchaDto">图形验证码信息</param>
        /// <returns></returns>
        [HttpPost("img")]
        public IActionResult ValidateImageCaptcha(ImgCaptchaDto imgCaptchaDto)
        {
            bool isCaptchaValid = _captchaService.ValidateImageCaptcha(imgCaptchaDto);
            if (isCaptchaValid)
            {
                HttpResponseDto httpResponseDto = new HttpResponseDto()
                {
                    IsSuccess = true,
                    Code = StatusCodes.Status200OK,
                    Message = "图形验证码验证成功"
                };
                var responJson = JsonConvert.SerializeObject(httpResponseDto);
                return Ok(responJson);
            }
            else
            {
                HttpResponseDto httpResponseDto = new HttpResponseDto()
                {
                    IsSuccess = false,
                    Code = StatusCodes.Status403Forbidden,
                    Message = "验证失败,请输入正确手机号及获取到的验证码"
                };
                var responJson = JsonConvert.SerializeObject(httpResponseDto);
                return StatusCode(StatusCodes.Status403Forbidden, responJson);
            }
        }

Http调用:详细调用参数和方式见下方接口在线文档。
图形验证码+短信验证码实战

五、短信验证码获取与校验:

获取:

代码:

/// <summary>
        /// 获取短信验证码
        /// </summary>
        /// <param name="msgCaptchaDto">短信验证码请求信息</param>
        /// <returns></returns>
        [HttpGet("msg")]
        public IActionResult GetMsgCaptcha([FromQuery]MsgCaptchaDto msgCaptchaDto)
        {
            var msgSendResult = _captchaService.GetMsgCaptcha(msgCaptchaDto);
            if (msgSendResult.Item1)
            {
                return Ok(msgSendResult.Item2);
            }
            else
            {
                return StatusCode(StatusCodes.Status403Forbidden, msgSendResult.Item2);
            }
        }

Http调用:详细调用参数和方式见下方接口在线文档。
图形验证码+短信验证码实战

图形验证码+短信验证码实战

校验:

代码:

/// <summary>
        /// 验证短信验证码
        /// </summary>
        /// <param name="msgCaptchaDto">短信验证码信息</param>
        /// <returns></returns>
        [HttpPost("msg")]
        public IActionResult ValidateMsgCaptcha(MsgCaptchaDto msgCaptchaDto)
        {
            var validateResult = _captchaService.ValidateMsgCaptcha(msgCaptchaDto);
            if (validateResult.Item1)
            {
                HttpResponseDto httpResponseDto = new HttpResponseDto()
                {
                    IsSuccess = true,
                    Code = StatusCodes.Status200OK,
                    Message = validateResult.Item2
                };
                var responJson = JsonConvert.SerializeObject(httpResponseDto);
                return Ok(responJson);
            }
            else
            {
                HttpResponseDto httpResponseDto = new HttpResponseDto()
                {
                    IsSuccess = false,
                    Code = StatusCodes.Status403Forbidden,
                    Message = validateResult.Item2
                };
                var responJson = JsonConvert.SerializeObject(httpResponseDto);
                return StatusCode(StatusCodes.Status403Forbidden, responJson);
            }
        }

Http调用:详细调用参数和方式见下方接口在线文档。
图形验证码+短信验证码实战

源码链接地址:

Gitee完整实例地址:

https://gitee.com/mingliang_it/Captcha

接口在线文档:

链接地址:

https://console-docs.apipost.cn/preview/82c61b0950bae0c8/924487d25ec3df36文章来源地址https://www.toymoban.com/news/detail-635389.html

到了这里,关于图形验证码+短信验证码实战的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Jmeter验证码图片识别注册接口压力测试实战_压测时,登录需要传图形验证码

    先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7 深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前! 因此收集整理了一份《2024年最新软件测试全套学习资料》

    2024年04月22日
    浏览(55)
  • 1.6 实战:Postman请求Get接口-获取用于登录的图形验证码

    上一小节我们学习了Postman的布局,对Postman有了一个整体的认知,本小节我们就来实操一下Get接口。 我们打开Postman,点击我们之前创建的请求”获取登录页验证码“。我们在地址栏里填入获取登录页验证码的接口地址。怎么查看这个接口地址呢?我们打开校园二手交易系统,

    2024年02月04日
    浏览(83)
  • 基于文本内容的垃圾短信识别实战

    背景: 垃圾短信形式日益多变,相关报告可以在下面网站查看 360互联网安全中心(http://zt.360.cn/report/) 目标: 基于短信文本内容,建立识别模型,准确地识别出垃圾短信,以解决垃圾短信过滤问题 1、数据探索 导入数据 更换列名 查看数据形状 整体查看数据 查看数据是否

    2024年02月16日
    浏览(48)
  • 【python】短信验证之腾讯云短信验证详细步骤

    注册一个腾讯云账户,腾讯云中提供了很多功能:云服务器、云储存器、云直播、云短信等很多功能。 注册地址:https://cloud.tencent.com/ 根据提示一步步进行注册即可, 实名注册时,什么行业、通讯等信息,按照自己的的实际情况填写即可,实在不知道的可以随便填。 腾讯云注

    2024年02月05日
    浏览(45)
  • 集成SpringCloudAlibaba短信服务 短信验证码

    1.1 SpringCloudAlibaba短信服务简介 短信服务(Short Message Service)是阿里云为用户提供的一种通信服务的能力。 产品优势:覆盖全面、高并发处理、消息堆积处理、开发管理简单、智能监控调度 产品功能:短信通知、短信验证码、推广短信、异步通知、数据统计 应用场景:短信

    2024年01月17日
    浏览(47)
  • 详解织梦dedecms短信验证码功能(阿里短信)

    现在大部分网站都需要用短信验证码,因为织梦官方没有短信验证码插件,所以写了几个短信验证码插件,一个使用的是阿里云的短信验证码接口,一个使用的是阿里大于的短信验证码接口,一个使用的是阿里通信短信验证码接口,另外一个使用的是云之讯的短信接口。下面

    2024年02月02日
    浏览(52)
  • 前端Vue自定义发送短信验证码弹框popup 实现剩余秒数计数 重发短信验证码

    前端Vue自定义发送短信验证码弹框popup 实现剩余秒数计数 重发短信验证码, 阅读全文下载完整代码请关注微信公众号: 前端组件开发 效果图如下: 实现代码如下: 使用方法 HTML代码实现部分 组件实现代码

    2024年02月11日
    浏览(40)
  • 短信验证码服务

    使用的是 阿里云 阿里云官网 1.找到 左上角侧边栏 -云通信 -短信服务 2.在快速学习测试处 ,按照步骤完成快速学习,绑定要测试的手机号,选专用 【测试模板】,自定义模板需要人工审核,要一个工作日 3.右上角 获取 AccessKey 管理,获取 选择子用户,这样即使 AccessKey 泄露

    2024年02月10日
    浏览(41)
  • python 爬虫 短信验证码

    在获得平台cookie的时候,发现很多平台都使用到了短信验证码来进行反扒,这种就挺抓头的,如果少量的账号还好,但是一旦账号较多,就很难受了,所以对于短信验证码的自动化获取就显得比较重要了,我来综述下我自己的解决过程吧。 总的来说就两种: 这个移动的‘无

    2024年02月02日
    浏览(40)
  • 短信验证码—Java实现

    在业务需求中我们经常会用到短信验证码,比如手机号登录、绑定手机号、忘记密码、敏感操作等,都可以通过短信验证码来保证操作的安全性,于是就记录下了一次开发的过程。 发送短信是一个比较慢的过程,因为需要用到第三方服务(腾讯云短信服务),因此我们 使用

    2024年02月09日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包