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

一、需求描述:

  • 图形验证码为,短信验证码为6位纯数字

  • 同一系统图片验证码缓存中只存在一个,没有有效期,每次刷新更新旧图形验证码

  • 短信验证码有效期2分钟

  • 每个手机号60秒内只能发送一次短信验证码,在服务器端执行校验

  • 同一个手机号在同一时间内可以有多个有效的短信验证码,根据不同系统类型区分

  • 每个短信验证码至多可被使用3次,无论和请求中的验证码是否匹配,随后立即作废,以防止暴力攻击

  • 发送短信验证码之前,先验证图形验证码是否正确

 二、图片验证码实现:

生成随机验证码字符串:

 ///         /// 获取随机验证码        ///         ///         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();        }

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

 ///         /// 生成随机验证码图片        ///         ///         ///         ///         ///         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短信验证码实现

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

获取:

代码:

  ///         /// 获取图片验证码        ///         /// 图形验证码请求信息        [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调用:详细调用参数和方式见下方接口在线文档

校验:

代码:

  ///         /// 验证图片验证码        ///         /// 图形验证码信息        ///         [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调用:详细调用参数和方式见下方接口在线文档

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

获取:

代码:

 ///         /// 获取短信验证码        ///         /// 短信验证码请求信息        ///         [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调用:详细调用参数和方式见下方接口在线文档

 校验:

代码:

///         /// 验证短信验证码        ///         /// 短信验证码信息        ///         [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调用:详细调用参数和方式见下方接口在线文档

阅读全文
资源下载
下载价格免费
下载说明:
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.shuli.cc/?p=15701,转载请注明出处。
0

评论0

显示验证码
没有账号?注册  忘记密码?