国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

圖形驗(yàn)證碼+短信驗(yàn)證碼實(shí)戰(zhàn)

這篇具有很好參考價(jià)值的文章主要介紹了圖形驗(yàn)證碼+短信驗(yàn)證碼實(shí)戰(zhàn)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

前言:

  上一篇分分享了基于阿里云實(shí)現(xiàn)的短信驗(yàn)證碼文章,考慮到為了防止登錄時(shí),非人工操作,頻繁獲取驗(yàn)證碼,趁熱打鐵,現(xiàn)在添加了圖片驗(yàn)證碼服務(wù)功能。借鑒網(wǎng)上傳統(tǒng)的做法,把實(shí)現(xiàn)這兩個(gè)驗(yàn)證的功能做成有個(gè)獨(dú)立的服務(wù),通過(guò)Http分別請(qǐng)求獲取校驗(yàn)圖片驗(yàn)證碼和短信驗(yàn)證碼。

一、需求描述:

  • 圖形驗(yàn)證碼為,短信驗(yàn)證碼為6位純數(shù)字
  • 同一系統(tǒng)圖片驗(yàn)證碼緩存中只存在一個(gè),沒有有效期,每次刷新更新舊圖形驗(yàn)證碼
  • 短信驗(yàn)證碼有效期2分鐘
  • 每個(gè)手機(jī)號(hào)60秒內(nèi)只能發(fā)送一次短信驗(yàn)證碼,在服務(wù)器端執(zhí)行校驗(yàn)
  • 同一個(gè)手機(jī)號(hào)在同一時(shí)間內(nèi)可以有多個(gè)有效的短信驗(yàn)證碼,根據(jù)不同系統(tǒng)類型區(qū)分
  • 每個(gè)短信驗(yàn)證碼至多可被使用3次,無(wú)論和請(qǐng)求中的驗(yàn)證碼是否匹配,隨后立即作廢,以防止暴力攻擊
  • 發(fā)送短信驗(yàn)證碼之前,先驗(yàn)證圖形驗(yàn)證碼是否正確

二、圖片驗(yàn)證碼實(shí)現(xiàn):

生成隨機(jī)驗(yàn)證碼字符串:

 /// <summary>
        /// 獲取隨機(jī)驗(yàn)證碼
        /// </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();
        }

隨機(jī)驗(yàn)證碼生成驗(yàn)證碼圖片:

 /// <summary>
        /// 生成隨機(jī)驗(yàn)證碼圖片
        /// </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();
                }
            }
        }

三、短信驗(yàn)證碼實(shí)現(xiàn):

見上篇:

傳送門:基于Aliyun短信驗(yàn)證碼實(shí)現(xiàn)

四、圖片驗(yàn)證碼獲取與校驗(yàn):

獲?。?/h3>

代碼:

  /// <summary>
        /// 獲取圖片驗(yàn)證碼
        /// </summary>
        /// <param name="imgCaptchaDto">圖形驗(yàn)證碼請(qǐng)求信息</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調(diào)用:詳細(xì)調(diào)用參數(shù)和方式見下方接口在線文檔。
圖形驗(yàn)證碼+短信驗(yàn)證碼實(shí)戰(zhàn)

校驗(yàn):

代碼:

 /// <summary>
        /// 驗(yàn)證圖片驗(yàn)證碼
        /// </summary>
        /// <param name="imgCaptchaDto">圖形驗(yàn)證碼信息</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 = "圖形驗(yàn)證碼驗(yàn)證成功"
                };
                var responJson = JsonConvert.SerializeObject(httpResponseDto);
                return Ok(responJson);
            }
            else
            {
                HttpResponseDto httpResponseDto = new HttpResponseDto()
                {
                    IsSuccess = false,
                    Code = StatusCodes.Status403Forbidden,
                    Message = "驗(yàn)證失敗,請(qǐng)輸入正確手機(jī)號(hào)及獲取到的驗(yàn)證碼"
                };
                var responJson = JsonConvert.SerializeObject(httpResponseDto);
                return StatusCode(StatusCodes.Status403Forbidden, responJson);
            }
        }

Http調(diào)用:詳細(xì)調(diào)用參數(shù)和方式見下方接口在線文檔。
圖形驗(yàn)證碼+短信驗(yàn)證碼實(shí)戰(zhàn)

五、短信驗(yàn)證碼獲取與校驗(yàn):

獲?。?/h3>

代碼:

/// <summary>
        /// 獲取短信驗(yàn)證碼
        /// </summary>
        /// <param name="msgCaptchaDto">短信驗(yàn)證碼請(qǐng)求信息</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調(diào)用:詳細(xì)調(diào)用參數(shù)和方式見下方接口在線文檔。
圖形驗(yàn)證碼+短信驗(yàn)證碼實(shí)戰(zhàn)

圖形驗(yàn)證碼+短信驗(yàn)證碼實(shí)戰(zhàn)

校驗(yàn):

代碼:

/// <summary>
        /// 驗(yàn)證短信驗(yàn)證碼
        /// </summary>
        /// <param name="msgCaptchaDto">短信驗(yàn)證碼信息</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調(diào)用:詳細(xì)調(diào)用參數(shù)和方式見下方接口在線文檔。
圖形驗(yàn)證碼+短信驗(yàn)證碼實(shí)戰(zhàn)

源碼鏈接地址:

Gitee完整實(shí)例地址:

https://gitee.com/mingliang_it/Captcha

接口在線文檔:

鏈接地址:

https://console-docs.apipost.cn/preview/82c61b0950bae0c8/924487d25ec3df36文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-635389.html

到了這里,關(guān)于圖形驗(yàn)證碼+短信驗(yàn)證碼實(shí)戰(zhàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Jmeter驗(yàn)證碼圖片識(shí)別注冊(cè)接口壓力測(cè)試實(shí)戰(zhàn)_壓測(cè)時(shí),登錄需要傳圖形驗(yàn)證碼

    Jmeter驗(yàn)證碼圖片識(shí)別注冊(cè)接口壓力測(cè)試實(shí)戰(zhàn)_壓測(cè)時(shí),登錄需要傳圖形驗(yàn)證碼

    先自我介紹一下,小編浙江大學(xué)畢業(yè),去過(guò)華為、字節(jié)跳動(dòng)等大廠,目前阿里P7 深知大多數(shù)程序員,想要提升技能,往往是自己摸索成長(zhǎng),但自己不成體系的自學(xué)效果低效又漫長(zhǎng),而且極易碰到天花板技術(shù)停滯不前! 因此收集整理了一份《2024年最新軟件測(cè)試全套學(xué)習(xí)資料》

    2024年04月22日
    瀏覽(30)
  • 1.6 實(shí)戰(zhàn):Postman請(qǐng)求Get接口-獲取用于登錄的圖形驗(yàn)證碼

    1.6 實(shí)戰(zhàn):Postman請(qǐng)求Get接口-獲取用于登錄的圖形驗(yàn)證碼

    上一小節(jié)我們學(xué)習(xí)了Postman的布局,對(duì)Postman有了一個(gè)整體的認(rèn)知,本小節(jié)我們就來(lái)實(shí)操一下Get接口。 我們打開Postman,點(diǎn)擊我們之前創(chuàng)建的請(qǐng)求”獲取登錄頁(yè)驗(yàn)證碼“。我們?cè)诘刂窓诶锾钊氆@取登錄頁(yè)驗(yàn)證碼的接口地址。怎么查看這個(gè)接口地址呢?我們打開校園二手交易系統(tǒng),

    2024年02月04日
    瀏覽(95)
  • 基于文本內(nèi)容的垃圾短信識(shí)別實(shí)戰(zhàn)

    基于文本內(nèi)容的垃圾短信識(shí)別實(shí)戰(zhàn)

    背景: 垃圾短信形式日益多變,相關(guān)報(bào)告可以在下面網(wǎng)站查看 360互聯(lián)網(wǎng)安全中心(http://zt.#/report/) 目標(biāo): 基于短信文本內(nèi)容,建立識(shí)別模型,準(zhǔn)確地識(shí)別出垃圾短信,以解決垃圾短信過(guò)濾問(wèn)題 1、數(shù)據(jù)探索 導(dǎo)入數(shù)據(jù) 更換列名 查看數(shù)據(jù)形狀 整體查看數(shù)據(jù) 查看數(shù)據(jù)是否

    2024年02月16日
    瀏覽(17)
  • 【python】短信驗(yàn)證之騰訊云短信驗(yàn)證詳細(xì)步驟

    【python】短信驗(yàn)證之騰訊云短信驗(yàn)證詳細(xì)步驟

    注冊(cè)一個(gè)騰訊云賬戶,騰訊云中提供了很多功能:云服務(wù)器、云儲(chǔ)存器、云直播、云短信等很多功能。 注冊(cè)地址:https://cloud.tencent.com/ 根據(jù)提示一步步進(jìn)行注冊(cè)即可, 實(shí)名注冊(cè)時(shí),什么行業(yè)、通訊等信息,按照自己的的實(shí)際情況填寫即可,實(shí)在不知道的可以隨便填。 騰訊云注

    2024年02月05日
    瀏覽(26)
  • 集成SpringCloudAlibaba短信服務(wù) 短信驗(yàn)證碼

    1.1 SpringCloudAlibaba短信服務(wù)簡(jiǎn)介 短信服務(wù)(Short Message Service)是阿里云為用戶提供的一種通信服務(wù)的能力。 產(chǎn)品優(yōu)勢(shì):覆蓋全面、高并發(fā)處理、消息堆積處理、開發(fā)管理簡(jiǎn)單、智能監(jiān)控調(diào)度 產(chǎn)品功能:短信通知、短信驗(yàn)證碼、推廣短信、異步通知、數(shù)據(jù)統(tǒng)計(jì) 應(yīng)用場(chǎng)景:短信

    2024年01月17日
    瀏覽(22)
  • 詳解織夢(mèng)dedecms短信驗(yàn)證碼功能(阿里短信)

    現(xiàn)在大部分網(wǎng)站都需要用短信驗(yàn)證碼,因?yàn)榭棄?mèng)官方?jīng)]有短信驗(yàn)證碼插件,所以寫了幾個(gè)短信驗(yàn)證碼插件,一個(gè)使用的是阿里云的短信驗(yàn)證碼接口,一個(gè)使用的是阿里大于的短信驗(yàn)證碼接口,一個(gè)使用的是阿里通信短信驗(yàn)證碼接口,另外一個(gè)使用的是云之訊的短信接口。下面

    2024年02月02日
    瀏覽(25)
  • 前端Vue自定義發(fā)送短信驗(yàn)證碼彈框popup 實(shí)現(xiàn)剩余秒數(shù)計(jì)數(shù) 重發(fā)短信驗(yàn)證碼

    前端Vue自定義發(fā)送短信驗(yàn)證碼彈框popup 實(shí)現(xiàn)剩余秒數(shù)計(jì)數(shù) 重發(fā)短信驗(yàn)證碼

    前端Vue自定義發(fā)送短信驗(yàn)證碼彈框popup 實(shí)現(xiàn)剩余秒數(shù)計(jì)數(shù) 重發(fā)短信驗(yàn)證碼, 閱讀全文下載完整代碼請(qǐng)關(guān)注微信公眾號(hào): 前端組件開發(fā) 效果圖如下: 實(shí)現(xiàn)代碼如下: 使用方法 HTML代碼實(shí)現(xiàn)部分 組件實(shí)現(xiàn)代碼

    2024年02月11日
    瀏覽(18)
  • 短信驗(yàn)證碼服務(wù)

    短信驗(yàn)證碼服務(wù)

    使用的是 阿里云 阿里云官網(wǎng) 1.找到 左上角側(cè)邊欄 -云通信 -短信服務(wù) 2.在快速學(xué)習(xí)測(cè)試處 ,按照步驟完成快速學(xué)習(xí),綁定要測(cè)試的手機(jī)號(hào),選專用 【測(cè)試模板】,自定義模板需要人工審核,要一個(gè)工作日 3.右上角 獲取 AccessKey 管理,獲取 選擇子用戶,這樣即使 AccessKey 泄露

    2024年02月10日
    瀏覽(19)
  • 短信驗(yàn)證碼—Java實(shí)現(xiàn)

    短信驗(yàn)證碼—Java實(shí)現(xiàn)

    在業(yè)務(wù)需求中我們經(jīng)常會(huì)用到短信驗(yàn)證碼,比如手機(jī)號(hào)登錄、綁定手機(jī)號(hào)、忘記密碼、敏感操作等,都可以通過(guò)短信驗(yàn)證碼來(lái)保證操作的安全性,于是就記錄下了一次開發(fā)的過(guò)程。 發(fā)送短信是一個(gè)比較慢的過(guò)程,因?yàn)樾枰玫降谌椒?wù)(騰訊云短信服務(wù)),因此我們 使用

    2024年02月09日
    瀏覽(15)
  • 短信驗(yàn)證碼

    阿里云短信 1.1 介紹 短信服務(wù)(Short Message Service)由阿里云提供短信平臺(tái),調(diào)用API即可發(fā)送驗(yàn)證碼、通知類和營(yíng)銷類短信;國(guó)內(nèi)驗(yàn)證短信秒級(jí)觸達(dá),到達(dá)率最高可達(dá)99%。 官方網(wǎng)站:https://www.aliyun.com/product/sms?spm=5176.19720258.J_8058803260.611.48192c4abPvXEp 1.2 代碼實(shí)現(xiàn) 2 自動(dòng)裝配 2.1

    2024年02月06日
    瀏覽(16)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包