I don't know how it works recently. I always like to study the implementation of some functions of some large sites. I think it is a bit interesting to read the implementation of verification codes for several large sites over the past two days.
Therefore, a similar mechanism is also implemented in. net. Let's take a look at the external performance of the verification code functions of these sites:
Look at QQ, there is a verification on the site can see, I provide a address here: http://pay.qq.com/login.shtml? Url = http://pay.qq.com/
Check whether the address for obtaining the verification code is: accept
The. NET implementation is different.
Look at this website to know: http://www.byf.com/member/member_login.aspx? Url = http % 3A % 2f % 2fwww.byf.com % 2 fmember % 2findex. aspx
The verification code on the login page is in the same domain as the current operation, at least certainly under the same site.
The address of the verification code is: http://www.byf.com/member/validate_img.aspx
This is something different from the outside. Let's take a look at what we can't see, and use httpwatch to look at QQ's:
GET/getimage HTTP/1.1
HTTP/1.1 200 OK
Server: Tencent HTTP Server
Accept-ranges: bytes
Pragma: No-Cache
Content-Length: 2589
Set-COOKIE: verifysession = success; Path =/; domain = QQ.com;
Connection: Close
Content-Type: image/JPEG
When the server writes the cookie verifysession to the client while requesting the verification code image, the server will obtain the cookie when logging on to the server.
Let's take a look at the common verification code:
GET/member/validate_img.aspx HTTP/1.1
HTTP/1.1 200 OK
Date: Wed, 07 May 2008 02:26:07 GMT
Server: Microsoft-Microsoft IIS/6.0
X-powered-by: ASP. NET
X-ASPnet-version: 1.1.4322
Cache-control: Private
Content-Type: image/GIF; charset = gb2312
Content-Length: 1953
Nothing, that is, the server saves the verification code data obtained by the request to the session. when the request is submitted, the server directly obtains the value in the verification code input box and compares it with the value in the session.
Let's take a look at Taobao's: http://member1.taobao.com/member/register.jhtml? _ Lang = default
Verification Code address: http://checkcode.taobao.com/auction/checkcode? Sessionid = 230bc9bc5e73ac5c7f49e6804a1e1d17
He did not write cookies to the client, but instead obtained the session for registration from the verification code side and saved it somewhere for verification at the time of submission.
We can also see that a small hack has a text in the header of the Verification Code:
Copyright (c) 2006 by Yahoo! China inconfigurated. All Rights Reserved. A little funny. Haha !!!
Let's take a look at the 163: http://reg.163.com/reg0.shtml
Like Taobao, Taobao does not write cookies. It verifies that the session on the application side is obtained.
Let's take a look at Baidu's:
HTTP/1.1 200 OK
Date: Wed, 07 May 2008 02:47:05 GMT
Server: Apache
Set-COOKIE: bduss = Hangzhou; Path =/; domain = .baidu.com
Expires: Mon, 26 Jul 1997 00:00:00 GMT
Last-modified: Wed, 07 May 2008 02:47:05 GMT
Cache-control: No-store, no-cache, must-revalidate
Cache-control: Post-check = 0, pre-check = 0
Pragma: No-Cache
Vary: Accept-Encoding
Content-encoding: Gzip
Content-Length: 2038
Connection: Close
Content-Type: image/PNG
In the same way as QQ, verify that the cookie is written to the application.
There are also Xunlei and Google. This is all the way... There must be a truth !!!
To sum up, these large sites separate the verification code server from the application server. There are two specific methods:
1. When obtaining the verification code, the verification code server writes the verification cookies to the client. When submitting the verification code, the server obtains the cookie and the submitted verification code, and then verifies the verification code on the Verification Code server.
2. When obtaining the verification code, send a session from the application side to the Verification Code server. When submitting the verification code, the server side sends the session from the application side and the submitted verification code to the Verification Code server for verification.
The analysis is here. Now that we have a clear understanding of the principles, let's do it.
The first problem to be solved is how to store the verification code data requested by the client and access the verification code from both sides.I solve it like this:
Using system;
Using system. configuration;
Using system. collections;
Using system. Collections. Generic;
Using system. text;
Namespace flyimg. Verify. Server
{
Public class codesession
{
/// <Summary>
/// Store the verification data linked list
/// </Summary>
Private Static shortlist <codesession> verifycodelist = new shortlist <codesession> ();
Private string _ sessionid;
Private string _ verifycode;
/// <Summary>
/// Constructor
/// </Summary>
/// <Param name = "strsessionid"> </param>
/// <Param name = "strverifycode"> </param>
Public codesession (string strsessionid, string strverifycode)
{
_ Sessionid = strsessionid;
_ Verifycode = strverifycode;
}
/// <Summary>
/// Add verification code data
/// </Summary>
/// <Param name = "strsessionid"> </param>
/// <Param name = "strverifycode"> </param>
/// <Returns> </returns>
Public static string add (string strsessionid, string strverifycode)
{
Bool bresult = false;
Inclulistnode <codesession> currentplay = new inclulistnode <codesession> (New codesession (strsessionid, strverifycode ));
Try
{
// Keep the linked list length to limit the number of client connections
If (verifycodelist. Count <Int. parse (configurationmanager. deleettings ["capacity"]. tostring ()))
{
Verifycodelist. addfirst (currentplay );
}
Else
{
Verifycodelist. removelast ();
Verifycodelist. addfirst (currentplay );
}
Bresult = true;
}
Catch
{
Bresult = false;
}
Return bresult. tostring ();
}
/// <Summary>
/// Delete the verification code data
/// </Summary>
/// <Param name = "strsessionid"> </param>
/// <Param name = "strverifycode"> </param>
Public static void remove (string strsessionid, string strverifycode)
{
Codesession = new codesession (strsessionid, strverifycode );
Verifycodelist. Remove (codesession );
}
/// <Summary>
/// Verify the verification code data
/// </Summary>
/// <Param name = "strsessionid"> </param>
/// <Param name = "strverifycode"> </param>
/// <Returns> </returns>
Public static string verify (string strsessionid, string strverifycode)
{
Int iresult = 0;
Foreach (codesession in verifycodelist)
{
If (codesession. _ sessionid = strsessionid & codesession. _ verifycode = strverifycode)
{
Iresult = 1;
Remove (strsessionid, strverifycode );
Break;
}
}
Return iresult. tostring ();
}
/// <Summary>
/// Clear verification data
/// </Summary>
Public static void clear ()
{
Verifycodelist. Clear ();
}
}
}
There are two main methods: add (ADD) and verify (verify). The problem is that applications on both sides can quickly access this area. I use socket
Because WebService is not used, it can be deployed in a distributed manner and the speed is fast enough. Configure the IP address of the Verification Code server in the verification code web configuration file.
After obtaining the verification code data on the Verification Code Web:
Try
{
// Add verification to verification Server
Common. addtoverifyserver (session. sessionid, this. strverifycode );
}
Catch (exception ex)
{
Logger. Add (ex. Message );
}
// Write cookie
General. setcookie ("verifykey", session. sessionid, "flyimg.cn ");
In this way, the task of the Verification Code web end is completed, and data in the verification code server is displayed:
When submitting:
Protected override void onpostting (Object sender, dataeventargs E)
{
If (string. isnullorempty (request. Form ["useraccounts"])
{
Strerror1 = "Enter the user name! ";
}
Else if (string. isnullorempty (request. Form ["userpwd"])
{
Strerror2 = "enter the password! ";
}
Else if (string. isnullorempty (request. Form ["verifycode"])
{
Strerror3 = "Please enter verification Ma! ";
}
Else
{
Bool bresult = false;
Try
{
// Verify with the verification Server
Bresult = Common. Verify (Toolkit. Common. General. getcookie ("verifykey"), request. Form ["verifycode"]);
}
Catch (exception ex)
{
Logger. Add (Ex );
}
If (bresult)
{
If (request. Form ["useraccounts"] = "admin" & request. Form ["userpwd"] = "123123 ")
{
General. setcookie ("user_id", "admin ");
String strreturnurl = request. querystring ["url"];
If (! String. isnullorempty (strreturnurl ))
{
Response. Redirect (httputility. urldecode (request. querystring ["url"]);
}
Else
{
Response. Redirect ("/upload ");
}
}
Else
{
Strerror2 = "the user name or password is incorrect! ";
}
}
Else
{
Strerror3 = "MFA verification error! ";
}
}
}
In this way, the verification is completed:
Okay. The function is implemented in this way. This is implemented in the first method. You can change it to the second method with a slight modification.
: Http://www.svnhost.cn/Download/Detail-108.shtml
The server uses an open-source socket class library, midapex. Net:
Http://www.cnblogs.com/dyj057/archive/2008/04/18/1160392.html