MVC uses extreme verification to make login verification code

Source: Internet
Author: User
In the previous project, if there is a need to use verification code, the basic is their own use of GDI + drawing out, simple and useful, but there are also some small problems, first, if less interference line, then the security is not very high, the verification code is easy to be recognized by the machine, if more than draw too much interference lines, robot recognition rate, The recognition rate of the human eye also decreased simultaneously (shocked cry). More importantly, GDI + draw the verification code is generally not very beautiful, if you do a cool landing interface is equipped with such a verification code, the wind is strange, ugly to the extreme.

Then browse the process of the Web page, found many many web site projects have used a verification code called the verification, the use of mobile slider to verify the way, convenient and beautiful. After a search, I learned that the official free version is enough to deal with most of the projects I have in hand, and I can't help but try to use the verification code as a login in the MVC learning process.

The official C # SDK and demo for the developer reference, but the WebForm version, the readability is not very high, and now the use of WebForm for the development of the site has basically disappeared, I will be in the official WebForm code based on it in the ASP. NET MVC program.

Registration of the Polar test

Go to the Background management screen after registering your account with the website, click Add Verification

After adding we can get ID and key

Complete validation Logic

1. First we need to introduce the official Geetestlib class

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 Verification C # SDK Base Library///</summary> public class Geetestlib {//<su  Mmary>///SDK version number//</summary> Public Const String Version = "3.2.0";  <summary>///SDK Development language///</summary> Public const String Sdklang = "CSharp";  <summary>///Verification 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>///Verification API Service Status session Key///</summary> Public const String Gtserverstatussessionkey = "Gt_  Server_status "; <summary&Gt  Verification of two validation form data Chllenge//</summary> Public const String Fngeetestchallenge = "Geetest_challenge"; <summary>///Verification two times Verify form data Validate//</summary> Public const String fngeetestvalidate = "Geetest_val  Idate "; <summary>///Verification two times Verify form data seccode//</summary> Public const String Fngeetestseccode = "Geetest_secco  De ";  Private String UserID = "";  Private String responsestr = "";  Private String Captchaid = "";   Private String Privatekey = "";  <summary>///Verify successful result string////</summary> Public const int successresult = 1;  <summary>///Certificate failure Test string///</summary> Public const int failresult = 0;   <summary>////Determines the result string for the robot///</summary> Public const string forbiddenresult = "forbidden";  <summary>//Geetestlib constructor///</summary>//<param name= "PublicKey" > Verified public key </param>// <param name= "Privatekey" > Verified private key </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>///validation initialization preprocessing///</summary>//<returns> initialization Results </returns> public Byte Preproc   ESS () {if (This.captchaid = = null) {Console.WriteLine ("PublicKey is null!");    } else {String challenge = This.registerchallenge (); if (challenge.     Length = = +) {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 = = +) {this.getsuccesspreprocessres (ChalleNge);    return 1;     } else {this.getfailpreprocessres ();    Console.WriteLine ("Server regist Challenge failed!");   }} return 0;  } public String Getresponsestr () {return this.responsestr; }///<summary>///Pre-processing failed after the return format string///</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>///Pre-processing standard string///</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 mode for verification///</summary>//<param name= "Challenge" >failback mode for use with Validat E decode the answer together, judge whether the verification is correct </param>///<param name= "Validate" >failback mode for decoding the answer with challenge, to determine whether the validation is correct </param  >//<param name= "Seccode" >failback mode, is actually a useless parameter </param>//<returns> Verification Results </returns> public int Failbackvalidaterequest (String challenge, String validate, String seccode) {if (!this.requestislegal (Challe   Nge, 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 < max) result = 40;   if (Math.Abs (Ans-result) < thread) return geetestlib.successresult;  else return geetestlib.failresult; The 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 two validations////</summary>/<param name= "challenge" > Unique identification of this authentication session &LT;/PARAM&GT  ; <param name= "Validate" > The validation results returned by the server side after the drag is complete </param>///<param Name= "Seccode" > Verify the results of the checksum, If Gt-server returns no equal to this value, it indicates a validation failure </param>///<returns> Two validation results </returns> public int Enhencedvalidaterequest (String challenge, String validate, String seccode) {if (!this.requestislegal (Challenge, Valida   TE, 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.fai   LResult; if (validate. Length > 0 && checkresultbyprivate (Challenge, validate)) {String query = "seccode=" + Seccode + "&use    R_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.creat    E (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 + "ge   Etest "+ 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); Send 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 (); Read back message Stream Myresponsestream = response.   GetResponseStream ();   StreamReader Mystreamreader = new StreamReader (Myresponsestream, encoding.getencoding ("Utf-8"));   String retstring = Mystreamreader.readtoend ();   Mystreamreader.close ();    Myresponsestream.close ();   return retstring; The 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) * + templist.elementat (1);  return result; } private int Decoderesponse (String challenge, String str) {if (str.   LENGTH&GT;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. Get the Verification code

Introducing the jquery Library

<script src= "~/content/plugins/jquery/jquery-1.8.2.min.js" ></script>

Add a div to place the verification code (it needs to be placed in the form form)

<div id= "Geetest-container" >

</div>
Add JS code to get verification code

<script> window.addeventlistener (' Load ', processgeetest);  function Processgeetest () {  $.ajax ({   //Get Id,challenge,success (failback enabled)   URL: "/login/geektest",   type: "Get",   DataType: "JSON",//Use JSONP format   success:function (data) {    //Use Initgeetest interface    // Parameter 1: Configuration parameters consistent with parameters accepted when creating an Geetest instance    //Parameter 2: Callback, Callback's first parameter Authenticode object, which can then be used to do events such as Appendto    initgeetest ({     GT: DATA.GT,     challenge:data.challenge, product     : "float",//form     offline:!data.success    },     handler);   }  ); }  var handler = function (captchaobj) {  //Adds the captcha to the element with ID captcha  captchaobj.appendto ("# Geetest-container ");   captchaobj.onsuccess = function (e) {   console.log (e);  }  }; </script>

The address "/login/geektest" of our asynchronous request in the Processgeetest method is the method that gets the verification code that needs to be performed in the background

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. Check the Verification code

Note that when the form is submitted, three parameters are passed to the background method (Geetest_challenge, Geetest_validate, Geetest_seccode), and the parameter is NULL if the verification code is not validated successfully.

The background verification method is:

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;}

In the form, we can determine if the verification code was successfully verified:

Public ActionResult Login () {if (! Checkgeetestresult ())  return Content ("No: Please complete the verification operation first.") "); ....}

The above is the whole content of this article, I hope that everyone's learning has helped, but also hope that we have a lot of support topic.alibabacloud.com.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.