以前のプロジェクトでは、検証コードを使用する必要がある場合は、基本的に GDI+ を使用して自分で描画していました。シンプルで使いやすいですが、最初に、干渉線が少ない場合にいくつかの小さな問題もあります。安全性はあまり高くありません。干渉する線を描きすぎると、認証コードが機械に認識されやすくなり、同時に人間の目の認識率も低下します。泣いています)。さらに重要なことは、GDI+ によって描画される検証コードは一般にあまり美しくありません。クールなログイン インターフェイスを作成しても、そのような検証コードを使用すると、描画スタイルが奇妙で非常に醜くなります。
青と白と黒と白の中から、その後 Web を閲覧する過程で、多くの Web サイト プロジェクトで Jiexian 検証と呼ばれる検証コードが使用されていることがわかりました。このコードはスライダーを動かすことで検証され、便利で美しいものです。いくつか検索した結果、手元にあるほとんどのプロジェクトには公式の無料バージョンで十分であることがわかりました。MVC の学習プロセス中に、ログイン検証コードとして Jiexian 検証を使用してみたくなりました。了 了方
開発者向けの SDK と DEMO のリファレンスは公式で提供されていますが、WebForm バージョンはあまり読みにくくなっており、Web サイト開発には基本的に WebForm を使用することになります。基本的にはASP.NET MVCプログラム内で使用します。
認証ロジックを完了します
1. まず、公式の Geetestlib クラスを導入します
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Security.Cryptography; using System.Net; using System.IO; namespace PMS.WebApp.Models { /// <summary> /// GeetestLib 极验验证C# SDK基本库 /// </summary> public class GeetestLib { /// <summary> /// SDK版本号 /// </summary> public const String version = "3.2.0"; /// <summary> /// SDK开发语言 /// </summary> public const String sdkLang = "csharp"; /// <summary> /// 极验验证API URL /// </summary> protected const String apiUrl = "http://api.geetest.com"; /// <summary> /// register url /// </summary> protected const String registerUrl = "/register.php"; /// <summary> /// validate url /// </summary> protected const String validateUrl = "/validate.php"; /// <summary> /// 极验验证API服务状态Session Key /// </summary> public const String gtServerStatusSessionKey = "gt_server_status"; /// <summary> /// 极验验证二次验证表单数据 Chllenge /// </summary> public const String fnGeetestChallenge = "geetest_challenge"; /// <summary> /// 极验验证二次验证表单数据 Validate /// </summary> public const String fnGeetestValidate = "geetest_validate"; /// <summary> /// 极验验证二次验证表单数据 Seccode /// </summary> public const String fnGeetestSeccode = "geetest_seccode"; private String userID = ""; private String responseStr = ""; private String captchaID = ""; private String privateKey = ""; /// <summary> /// 验证成功结果字符串 /// </summary> public const int successResult = 1; /// <summary> /// 证结失败验果字符串 /// </summary> public const int failResult = 0; /// <summary> /// 判定为机器人结果字符串 /// </summary> public const String forbiddenResult = "forbidden"; /// <summary> /// GeetestLib构造函数 /// </summary> /// <param name="publicKey">极验验证公钥</param> /// <param name="privateKey">极验验证私钥</param> public GeetestLib(String publicKey, String privateKey) { this.privateKey = privateKey; this.captchaID = publicKey; } private int getRandomNum() { Random rand =new Random(); int randRes = rand.Next(100); return randRes; } /// <summary> /// 验证初始化预处理 /// </summary> /// <returns>初始化结果</returns> public Byte preProcess() { if (this.captchaID == null) { Console.WriteLine("publicKey is null!"); } else { String challenge = this.registerChallenge(); if (challenge.Length == 32) { this.getSuccessPreProcessRes(challenge); return 1; } else { this.getFailPreProcessRes(); Console.WriteLine("Server regist challenge failed!"); } } return 0; } public Byte preProcess(String userID) { if (this.captchaID == null) { Console.WriteLine("publicKey is null!"); } else { this.userID = userID; String challenge = this.registerChallenge(); if (challenge.Length == 32) { this.getSuccessPreProcessRes(challenge); return 1; } else { this.getFailPreProcessRes(); Console.WriteLine("Server regist challenge failed!"); } } return 0; } public String getResponseStr() { return this.responseStr; } /// <summary> /// 预处理失败后的返回格式串 /// </summary> private void getFailPreProcessRes() { int rand1 = this.getRandomNum(); int rand2 = this.getRandomNum(); String md5Str1 = this.md5Encode(rand1 + ""); String md5Str2 = this.md5Encode(rand2 + ""); String challenge = md5Str1 + md5Str2.Substring(0, 2); this.responseStr = "{" + string.Format( "\"success\":{0},\"gt\":\"{1}\",\"challenge\":\"{2}\"", 0, this.captchaID, challenge) + "}"; } /// <summary> /// 预处理成功后的标准串 /// </summary> private void getSuccessPreProcessRes(String challenge) { challenge = this.md5Encode(challenge + this.privateKey); this.responseStr ="{" + string.Format( "\"success\":{0},\"gt\":\"{1}\",\"challenge\":\"{2}\"", 1, this.captchaID, challenge) + "}"; } /// <summary> /// failback模式的验证方式 /// </summary> /// <param name="challenge">failback模式下用于与validate一起解码答案, 判断验证是否正确</param> /// <param name="validate">failback模式下用于与challenge一起解码答案, 判断验证是否正确</param> /// <param name="seccode">failback模式下,其实是个没用的参数</param> /// <returns>验证结果</returns> public int failbackValidateRequest(String challenge, String validate, String seccode) { if (!this.requestIsLegal(challenge, validate, seccode)) return GeetestLib.failResult; String[] validateStr = validate.Split('_'); String encodeAns = validateStr[0]; String encodeFullBgImgIndex = validateStr[1]; String encodeImgGrpIndex = validateStr[2]; int decodeAns = this.decodeResponse(challenge, encodeAns); int decodeFullBgImgIndex = this.decodeResponse(challenge, encodeFullBgImgIndex); int decodeImgGrpIndex = this.decodeResponse(challenge, encodeImgGrpIndex); int validateResult = this.validateFailImage(decodeAns, decodeFullBgImgIndex, decodeImgGrpIndex); return validateResult; } private int validateFailImage(int ans, int full_bg_index, int img_grp_index) { const int thread = 3; String full_bg_name = this.md5Encode(full_bg_index + "").Substring(0, 10); String bg_name = md5Encode(img_grp_index + "").Substring(10, 10); String answer_decode = ""; for (int i = 0;i < 9; i++) { if (i % 2 == 0) answer_decode += full_bg_name.ElementAt(i); else if (i % 2 == 1) answer_decode += bg_name.ElementAt(i); } String x_decode = answer_decode.Substring(4); int x_int = Convert.ToInt32(x_decode, 16); int result = x_int % 200; if (result < 40) result = 40; if (Math.Abs(ans - result) < thread) return GeetestLib.successResult; else return GeetestLib.failResult; } private Boolean requestIsLegal(String challenge, String validate, String seccode) { if (challenge.Equals(string.Empty) || validate.Equals(string.Empty) || seccode.Equals(string.Empty)) return false; return true; } /// <summary> /// 向gt-server进行二次验证 /// </summary> /// <param name="challenge">本次验证会话的唯一标识</param> /// <param name="validate">拖动完成后server端返回的验证结果标识字符串</param> /// <param name="seccode">验证结果的校验码,如果gt-server返回的不与这个值相等则表明验证失败</param> /// <returns>二次验证结果</returns> public int enhencedValidateRequest(String challenge, String validate, String seccode) { if (!this.requestIsLegal(challenge, validate, seccode)) return GeetestLib.failResult; if (validate.Length > 0 && checkResultByPrivate(challenge, validate)) { String query = "seccode=" + seccode + "&sdk=csharp_" + GeetestLib.version; String response = ""; try { response = postValidate(query); } catch (Exception e) { Console.WriteLine(e); } if (response.Equals(md5Encode(seccode))) { return GeetestLib.successResult; } } return GeetestLib.failResult; } public int enhencedValidateRequest(String challenge, String validate, String seccode, String userID) { if (!this.requestIsLegal(challenge, validate, seccode)) return GeetestLib.failResult; if (validate.Length > 0 && checkResultByPrivate(challenge, validate)) { String query = "seccode=" + seccode + "&user_id=" + userID + "&sdk=csharp_" + GeetestLib.version; String response = ""; try { response = postValidate(query); } catch (Exception e) { Console.WriteLine(e); } if (response.Equals(md5Encode(seccode))) { return GeetestLib.successResult; } } return GeetestLib.failResult; } private String readContentFromGet(String url) { try { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.Timeout = 20000; HttpWebResponse response = (HttpWebResponse)request.GetResponse(); Stream myResponseStream = response.GetResponseStream(); StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8")); String retString = myStreamReader.ReadToEnd(); myStreamReader.Close(); myResponseStream.Close(); return retString; } catch { return ""; } } private String registerChallenge() { String url = ""; if (string.Empty.Equals(this.userID)) { url = string.Format("{0}{1}?gt={2}", GeetestLib.apiUrl, GeetestLib.registerUrl, this.captchaID); } else { url = string.Format("{0}{1}?gt={2}&user_id={3}", GeetestLib.apiUrl, GeetestLib.registerUrl, this.captchaID, this.userID); } string retString = this.readContentFromGet(url); return retString; } private Boolean checkResultByPrivate(String origin, String validate) { String encodeStr = md5Encode(privateKey + "geetest" + origin); return validate.Equals(encodeStr); } private String postValidate(String data) { String url = string.Format("{0}{1}", GeetestLib.apiUrl, GeetestLib.validateUrl); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; request.ContentLength = Encoding.UTF8.GetByteCount(data); // 发送数据 Stream myRequestStream = request.GetRequestStream(); byte[] requestBytes = System.Text.Encoding.ASCII.GetBytes(data); myRequestStream.Write(requestBytes, 0, requestBytes.Length); myRequestStream.Close(); HttpWebResponse response = (HttpWebResponse)request.GetResponse(); // 读取返回信息 Stream myResponseStream = response.GetResponseStream(); StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8")); string retString = myStreamReader.ReadToEnd(); myStreamReader.Close(); myResponseStream.Close(); return retString; } private int decodeRandBase(String challenge) { String baseStr = challenge.Substring(32, 2); List<int> tempList = new List<int>(); for(int i = 0; i < baseStr.Length; i++) { int tempAscii = (int)baseStr[i]; tempList.Add((tempAscii > 57) ? (tempAscii - 87) : (tempAscii - 48)); } int result = tempList.ElementAt(0) * 36 + tempList.ElementAt(1); return result; } private int decodeResponse(String challenge, String str) { if (str.Length>100) return 0; int[] shuzi = new int[] { 1, 2, 5, 10, 50}; String chongfu = ""; Hashtable key = new Hashtable(); int count = 0; for (int i=0;i<challenge.Length;i++) { String item = challenge.ElementAt(i) + ""; if (chongfu.Contains(item)) continue; else { int value = shuzi[count % 5]; chongfu += item; count++; key.Add(item, value); } } int res = 0; for (int i = 0; i < str.Length; i++) res += (int)key[str[i]+""]; res = res - this.decodeRandBase(challenge); return res; } private String md5Encode(String plainText) { MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider(); string t2 = BitConverter.ToString(md5.ComputeHash(UTF8Encoding.Default.GetBytes(plainText))); t2 = t2.Replace("-", ""); t2 = t2.ToLower(); return t2; } } }2. 検証コードを取得しますJquery ライブラリを導入します > ;
検証コードを取得するための JS コードを追加します
<script> window.addEventListener('load', processGeeTest); function processGeeTest() { $.ajax({ // 获取id,challenge,success(是否启用failback) url: "/Login/GeekTest", type: "get", dataType: "json", // 使用jsonp格式 success: function (data) { // 使用initGeetest接口 // 参数1:配置参数,与创建Geetest实例时接受的参数一致 // 参数2:回调,回调的第一个参数验证码对象,之后可以使用它做appendTo之类的事件 initGeetest({ gt: data.gt, challenge: data.challenge, product: "float", // 产品形式 offline: !data.success }, handler); } }); } var handler = function (captchaObj) { // 将验证码加到id为captcha的元素里 captchaObj.appendTo("#geetest-container"); captchaObj.onSuccess = function (e) { console.log(e); } }; </script>
processGeeTest メソッド内の非同期リクエスト「/Login/GeekTest」のアドレスは、検証コードを取得するためのものであり、バックグラウンドで実行する必要があるメソッドです
public ActionResult GeekTest() { return Content(GetCaptcha(),"application/json"); } private string GetCaptcha() { var geetest = new GeetestLib("3594e0d834df77cedc7351a02b5b06a4", "b961c8081ce88af7e32a3f45d00dff84"); var gtServerStatus = geetest.preProcess(); Session[GeetestLib.gtServerStatusSessionKey] = gtServerStatus; return geetest.getResponseStr(); }
3. 検証コードを検証します
フォームを送信するときに、geetest に関連する 3 つのパラメーター (geetest_challenge、geetest_validate、geetest_seccode) が検証コードの検証に失敗した場合に渡されることに注意してください。空の。
バックグラウンド検証方法は次のとおりです:
private bool CheckGeeTestResult() { var geetest = new GeetestLib("3594e0d834df77cedc7351a02b5b06a4", "b961c8081ce88af7e32a3f45d00dff84 "); var gtServerStatusCode = (byte)Session[GeetestLib.gtServerStatusSessionKey]; var userId = (string)Session["userID"]; var challenge = Request.Form.Get(GeetestLib.fnGeetestChallenge); var validate = Request.Form.Get(GeetestLib.fnGeetestValidate); var seccode = Request.Form.Get(GeetestLib.fnGeetestSeccode); var result = gtServerStatusCode == 1 ? geetest.enhencedValidateRequest(challenge, validate, seccode, userId) : geetest.failbackValidateRequest(challenge, validate, seccode); return result == 1; }🎜 検証コードが正常に検証されたかどうかは、次の形式で判断できます: 🎜
public ActionResult Login() { if (!CheckGeeTestResult()) return Content("no:请先完成验证操作。"); .... }🎜 以上がこの記事の全内容です。私も皆さんの学習に役立つことを願っています。皆さんも PHP 中国語 Web サイトにもっと注目していただければ幸いです。 🎜🎜 Jiexianverification を使用してログイン確認コードを作成する MVC に関連するその他の記事については、PHP 中国語 Web サイトに注目してください。 🎜

C#.NETの設計パターンには、Singletonパターンと依存関係の注入が含まれます。 1.シングルトンモードは、クラスに1つのインスタンスしかないことを保証します。これは、グローバルアクセスポイントが必要なシナリオに適していますが、安全性と虐待の問題をスレッドすることに注意する必要があります。 2。依存関係の噴射により、依存関係を注入することにより、コードの柔軟性とテスト可能性が向上します。多くの場合、コンストラクターの注入に使用されますが、複雑さを高めるために過度の使用を避ける必要があります。

C#.NETは、ゲーム開発、金融サービス、モノのインターネット、クラウドコンピューティングの分野で現代世界で広く使用されています。 1)ゲーム開発では、C#を使用してUnityエンジンを介してプログラムします。 2)金融サービスの分野では、C#.NETが高性能取引システムとデータ分析ツールの開発に使用されます。 3)IoTおよびクラウドコンピューティングに関して、C#.NETはAzure Servicesを通じてサポートを提供して、デバイス制御ロジックとデータ処理を開発します。

.NETFRAMEWORKISWINDOWS-CENTRIC、while.netcore/5/6supportscross-platformdevelopment.1).netframework、2002年以来、isidealforwindowsprimitedincross-platformcapabilities.2).netcore、andtseverutions(andtseverutions(andtseverution)

C#.NET開発者コミュニティは、次のような豊富なリソースとサポートを提供します。1。Microsoftの公式文書、2。StackoverflowやRedditなどのコミュニティフォーラム、3。Githubのオープンソースプロジェクト。これらのリソースは、開発者が基本的な学習から高度なアプリケーションまでプログラミングスキルを向上させるのに役立ちます。

C#.NETの利点には以下が含まれます。1)非同期プログラミングなどの言語機能により、開発が簡素化されます。 2)パフォーマンスと信頼性、JITコンピレーションとゴミ収集メカニズムによる効率の向上。 3)クロスプラットフォームサポート、.NetCoreはアプリケーションシナリオを拡張します。 4)Webからデスクトップ、ゲーム開発までの優れたパフォーマンスを備えた幅広い実用的なアプリケーション。

C#は常に.NETに結び付けられているわけではありません。 1)C#は、モノランタイム環境で実行でき、LinuxおよびMacOSに適しています。 2)Unityゲームエンジンでは、C#はスクリプトに使用され、.NETフレームワークに依存しません。 3)C#は、.NetMicRoframeworkなどの埋め込みシステム開発にも使用できます。

C#は、.NETエコシステムで中核的な役割を果たし、開発者にとって好ましい言語です。 1)C#は、C、C、Javaの利点を組み合わせた効率的で使いやすいプログラミング方法を提供します。 2).NETランタイム(CLR)を介して実行して、効率的なクロスプラットフォーム操作を確保します。 3)C#は、LINQや非同期プログラミングなどの基本的な使用から高度な使用をサポートします。 4)最適化とベストプラクティスには、StringBuilderおよび非同期プログラミングを使用して、パフォーマンスと保守性を向上させることが含まれます。

C#は、2000年にMicrosoftがリリースしたプログラミング言語で、CのパワーとJavaのシンプルさを組み合わせることを目指しています。 1.C#は、カプセル化、継承、多型をサポートするタイプセーフ、オブジェクト指向のプログラミング言語です。 2. C#のコンパイルプロセスは、コードを中間言語(IL)に変換し、.NETランタイム環境(CLR)でマシンコード実行にコンパイルします。 3. C#の基本的な使用法には、可変宣言、制御フロー、関数の定義が含まれ、高度な使用法には非同期プログラミング、LINQ、およびデリゲートなどが含まれます。4。一般的なエラーには、デバッガー、例外処理、ロギングを介してデバッグできるタイプミスマッチおよびヌル参照の例外が含まれます。 5.パフォーマンスの最適化の提案には、LINQの使用、非同期プログラミング、およびコードの読み取り可能性の向上が含まれます。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

VSCode Windows 64 ビットのダウンロード
Microsoft によって発売された無料で強力な IDE エディター

SublimeText3 英語版
推奨: Win バージョン、コードプロンプトをサポート!

SublimeText3 Linux 新バージョン
SublimeText3 Linux 最新バージョン

ドリームウィーバー CS6
ビジュアル Web 開発ツール
