日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

QQ空间及邮箱验证码登录的校验方式及自动登录的解决方案

發(fā)布時(shí)間:2024/7/19 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 QQ空间及邮箱验证码登录的校验方式及自动登录的解决方案 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

目前有很多的SNS社區(qū)或類SNS的網(wǎng)站,例如開心、51、校內(nèi)等,但是發(fā)現(xiàn)大多數(shù)社區(qū)在邀請好友的時(shí)候都沒有提供對QQ郵箱或者QQ空間好友列表獲取的功能,不過似乎海內(nèi)支持,但是網(wǎng)上相關(guān)QQ的文章還不是很多,希望這篇文章能給你帶來一些幫助。

QQ空間及郵箱登陸的校驗(yàn)方式:

QQ空間及郵箱登陸的時(shí)候,用戶輸入的密碼首先會(huì)被頁面中的一段Js加密,然后加密過后的密碼會(huì)加上驗(yàn)證碼形成一個(gè)新的字串,接著這個(gè)新的字串被MD5(32位)加密,加密過后形成最終的密碼,這就是我們?yōu)槭裁唇?jīng)常會(huì)發(fā)現(xiàn)我們在提交的時(shí)候我們的密碼框中的密碼個(gè)數(shù)會(huì)增長的原因,接著在你提交的時(shí)候,當(dāng)前的這個(gè)請求會(huì)將前一次獲取驗(yàn)證碼返回的set-cookie值加入到當(dāng)前請求頭的cookie中以保持驗(yàn)證碼請求與當(dāng)前請求的一致性,然后再一并將新的密碼和用戶名Post到QQ的服務(wù)器上去。

好了,看了上面的QQ校驗(yàn)方式以后,我們再來看看怎樣使用代碼來登錄QQ空間及郵箱來獲取我們需要的好友和聯(lián)系人。

QQ空間及郵箱自動(dòng)登錄獲取聯(lián)系人的解決方案:

QQ空間及郵箱登陸首先我們需要將用戶輸入的密碼進(jìn)行Js加密,但是我們在使用代碼登錄的時(shí)候我們并沒有使用到瀏覽器,那我們怎樣驅(qū)動(dòng)Js呢?不用怕,在Java和.NET中都有相應(yīng)的方式在服務(wù)器代碼端驅(qū)動(dòng)JS,這里著重講一下.NET的方法:

首先到微軟的網(wǎng)站上下載Windows Script Control,它是一個(gè)ActiveX(R) 控件。下載安裝完成后,新建一個(gè)C#應(yīng)用程序項(xiàng)目,在解決方案資源管理器中選中引用節(jié)點(diǎn), 右鍵點(diǎn)擊選擇添加引用菜單,彈出添加引用對話框,單擊瀏覽找到安裝Windows Script Control的目錄,選取msscript.ocx文件確定。那么在引用節(jié)點(diǎn)下會(huì)增加一個(gè)MSScriptControl組件,下面是他Interop 后的所有對象。

<!--[if !vml]--><!--[endif]-->

ScriptControl 對支持 ActiveX(TM) Script 的宿主 Script 引擎提供簡單接口。接下來我們對被轉(zhuǎn)化成ScriptControlClass類的ScriptControl的屬性和方法進(jìn)行一些說明。

屬性

AllowUI 屬性:應(yīng)用于 ScriptControl 本身或 Scirpt 引擎顯示的用戶界面元素,可讀寫。

CodeObject 屬性:返回對象,該對象用于調(diào)用指定模塊的公用成員。只讀。

Error 屬性:返回 Error 對象,其中包含所發(fā)生的最后一個(gè)錯(cuò)誤的相關(guān)詳細(xì)信息。只讀。

Language 屬性:設(shè)置或返回正在使用的 Script 語言名稱。可讀寫。

Modules 屬性:為 ScriptControl 對象返回模塊集合。只讀。

Procedures 屬性:返回在指定模塊中定義的過程集合。只讀。

SitehWnd 屬性:設(shè)置或返回窗口的 hWnd,通過執(zhí)行 Script 代碼,此窗口用于顯示對話框和其他用戶界面元素。可讀寫。

State 屬性:設(shè)置或返回 ScriptControl 對象的模式。可讀寫。

Timeout 屬性:設(shè)置或返回時(shí)間(毫秒),此時(shí)間后用戶可選擇中止 Script 代碼的執(zhí)行或允許代碼繼續(xù)執(zhí)行。可讀寫。

UseSafeSubset 屬性:設(shè)置或返回 Boolean 值,指明宿主應(yīng)用程序是否有保密性要求。如果宿主應(yīng)用程序需要安全控制,則 UseSafeSubset 為 True,否則為 False。可讀寫。

方法

AddCode 方法:向模塊添加指定代碼。可多次調(diào)用 AddCode 方法。

AddObject 方法:使主機(jī)對象模型對 Script 引擎可用。

Eval 方法:計(jì)算表達(dá)式并返回結(jié)果。

ExecuteStatement 方法:執(zhí)行指定的語句。

Reset 方法:放棄所有已經(jīng)添加到 ScriptControl 中的 Script 代碼和對象。

Run 方法:運(yùn)行指定過程。

事件

Error 事件:出現(xiàn)運(yùn)行時(shí)錯(cuò)誤時(shí),發(fā)生此事件。

Timeout 事件:當(dāng)超出了 Timeout 屬性指定的時(shí)間且用戶在結(jié)果對話框中選定了 End 時(shí),發(fā)生此事件。

說明:

AllowUI 屬性如果設(shè)置為false,則顯示對話框之類的語句不起作用,如在 VBScript 中MsgBox 語句,JavaScript中的alert等,并且如果執(zhí)行的腳本超出TimeOut設(shè)置的毫秒數(shù),也不會(huì)跳出超出時(shí)間提醒的對話框,反之則相反;重新設(shè) 置 Language 屬性會(huì)清空AddCode加載的代碼;對于TimeOut屬性,發(fā)生超時(shí)時(shí),ScriptControl 檢查對象的 AllowUI 屬性,確定是否允許顯示用戶界面元素。

為了使控件更容易使用,用ScriptEngine類封裝一下,下面是完整代碼:

using System;

using MSScriptControl;

using System.Text;

namespace ScriptNameSpace

{

/// <summary>

/// 腳本類型

/// </summary>

public enum ScriptLanguage

{

/// <summary>

/// JScript腳本語言

/// </summary>

JScript,

/// <summary>

/// VBscript腳本語言

/// </summary>

VBscript,

/// <summary>

/// JavaScript腳本語言

/// </summary>

JavaScript

}

/// <summary>

/// 腳本運(yùn)行錯(cuò)誤代理

/// </summary>

public delegate void RunErrorHandler();

/// <summary>

/// 腳本運(yùn)行超時(shí)代理

/// </summary>

public delegate void RunTimeoutHandler();

/// <summary>

/// ScriptEngine類

/// </summary>

public class ScriptEngine

{

private ScriptControl msc;

//定義腳本運(yùn)行錯(cuò)誤事件

public event RunErrorHandler RunError;

//定義腳本運(yùn)行超時(shí)事件

public event RunTimeoutHandler RunTimeout;

/// <summary>

///構(gòu)造函數(shù)

/// </summary>

public ScriptEngine()

: this(ScriptLanguage.VBscript)

{ }

/// <summary>

/// 構(gòu)造函數(shù)

/// </summary>

/// <param name="language">腳本類型</param>

public ScriptEngine(ScriptLanguage language)

{

this.msc = new ScriptControlClass();

this.msc.UseSafeSubset = true;

this.msc.Language = language.ToString();

((DScriptControlSource_Event)this.msc).Error += new DScriptControlSource_ErrorEventHandler(ScriptEngine_Error);

((DScriptControlSource_Event)this.msc).Timeout += new DScriptControlSource_TimeoutEventHandler(ScriptEngine_Timeout);

}

/// <summary>

/// 運(yùn)行Eval方法

/// </summary>

/// <param name="expression">表達(dá)式</param>

/// <param name="codeBody">函數(shù)體</param>

/// <returns>返回值object</returns>

public object Eval(string expression, string codeBody)

{

msc.AddCode(codeBody);

return msc.Eval(expression);

}

/// <summary>

/// 運(yùn)行Eval方法

/// </summary>

/// <param name="language">腳本語言</param>

/// <param name="expression">表達(dá)式</param>

/// <param name="codeBody">函數(shù)體</param>

/// <returns>返回值object</returns>

public object Eval(ScriptLanguage language, string expression, string codeBody)

{

if (this.Language != language)

this.Language = language;

return Eval(expression, codeBody);

}

/// <summary>

/// 運(yùn)行Run方法

/// </summary>

/// <param name="mainFunctionName">入口函數(shù)名稱</param>

/// <param name="parameters">參數(shù)</param>

/// <param name="codeBody">函數(shù)體</param>

/// <returns>返回值object</returns>

public object Run(string mainFunctionName, object[] parameters, string codeBody)

{

this.msc.AddCode(codeBody);

return msc.Run(mainFunctionName, ref parameters);

}

/// <summary>

/// 運(yùn)行Run方法

/// </summary>

/// <param name="language">腳本語言</param>

/// <param name="mainFunctionName">入口函數(shù)名稱</param>

/// <param name="parameters">參數(shù)</param>

/// <param name="codeBody">函數(shù)體</param>

/// <returns>返回值object</returns>

public object Run(ScriptLanguage language, string mainFunctionName, object[] parameters, string codeBody)

{

if (this.Language != language)

this.Language = language;

return Run(mainFunctionName, parameters, codeBody);

}

/// <summary>

/// 放棄所有已經(jīng)添加到 ScriptControl 中的 Script 代碼和對象

/// </summary>

public void Reset()

{

this.msc.Reset();

}

/// <summary>

/// 獲取或設(shè)置腳本語言

/// </summary>

public ScriptLanguage Language

{

get { return (ScriptLanguage)Enum.Parse(typeof(ScriptLanguage), this.msc.Language, false); }

set { this.msc.Language = value.ToString(); }

}

/// <summary>

/// 獲取或設(shè)置腳本執(zhí)行時(shí)間,單位為毫秒

/// </summary>

public int Timeout

{

get { return 0; }

}

/// <summary>

/// 設(shè)置是否顯示用戶界面元素

/// </summary>

public bool AllowUI

{

get { return this.msc.AllowUI; }

set { this.msc.AllowUI = value; }

}

/// <summary>

/// 宿主應(yīng)用程序是否有保密性要求

/// </summary>

public bool UseSafeSubset

{

get { return this.msc.UseSafeSubset; }

set { this.msc.UseSafeSubset = true; }

}

/// <summary>

/// RunError事件激發(fā)

/// </summary>

private void OnError()

{

if (RunError != null)

RunError();

}

/// <summary>

/// OnTimeout事件激發(fā)

/// </summary>

private void OnTimeout()

{

if (RunTimeout != null)

RunTimeout();

}

private void ScriptEngine_Error()

{

OnError();

}

private void ScriptEngine_Timeout()

{

OnTimeout();

}

}

}

在找到.NET驅(qū)動(dòng)JS的方法以后,那么我們還需要找到QQ用來加密的那個(gè)JS文件,具體的JS文件大家可以到QQ的登錄頁面去DownLoad,如果不知道是哪一個(gè)JS大家可以通過抓包的方式去找到,這里就不再贅述了。下面我們就可以用MSScriptControl來驅(qū)動(dòng)JS獲取第一次加密的密碼了,方法如下:

/// <summary>

/// 得到第一次加密后的密碼

/// </summary>

/// <param name="jsFilePath">js文件</param>

/// <param name="funcName">加密的方法名</param>

/// <param name="paramers">加密方法需要傳進(jìn)的參數(shù)(一個(gè)是密碼,另一個(gè)是頁面上可獲取的一個(gè)標(biāo)志碼)</param>

/// <returns>加密過后的密碼</returns>

private object GetPassword(string jsFilePath, string funcName, params object[] paramers)

{

StreamReader reader = new StreamReader(jsFilePath);

string sScript = reader.ReadToEnd();

ScriptEngine se = new ScriptEngine(ScriptLanguage.JavaScript);

object obj = se.Run(funcName, paramers, sScript);

return obj;

}

通過上面的這個(gè)函數(shù)我們就可以對密碼進(jìn)行第一次加密了,下一步我們需要獲取驗(yàn)證碼。

我們可以使用HttpWebRequest類來Get請求這個(gè)地址:http://ptlogin2.qq.com/getimage來獲取驗(yàn)證碼,不過一定要記住把這次請求返回的cookie保存下來,我們可以將它保存到CookieContainer對象中,以便將這次返回的cookie加入到登錄POST請求的頭當(dāng)中保持前后請求的一致性。

現(xiàn)在我們將獲得的驗(yàn)證碼轉(zhuǎn)化成流或者其他的方式供不同的平臺(tái)輸出,我們發(fā)現(xiàn)QQ空間及郵箱的驗(yàn)證碼生成的圖像不是太復(fù)雜,所以可以考慮使用圖像識別的方式自動(dòng)的獲取圖像對應(yīng)的字符(現(xiàn)在有很多第三方驗(yàn)證碼識別軟件),當(dāng)然為了成功率考慮,最好還是讓用戶手動(dòng)的輸入。

好了有了驗(yàn)證碼了,我們現(xiàn)在就將驗(yàn)證碼字符加上剛剛我們加過密的密碼形成新字串,再通過MD5加密

string pwd=FormsAuthentication.HashPasswordForStoringInConfigFile(this.Password, "MD5").ToLower()

形成最終我們需要的密碼。

最后我們就可以將用戶輸入的用戶名、密碼一并POST到QQ相應(yīng)的地址上去,這樣我們就成功登陸QQ空間或郵箱了。登錄成功過后你當(dāng)然就可以獲取聯(lián)系人好友等等的操作了。

好了,文章就寫到這了,希望對大家有用。^^ Brave chen

轉(zhuǎn)載于:https://www.cnblogs.com/l1b2q31/articles/2767269.html

總結(jié)

以上是生活随笔為你收集整理的QQ空间及邮箱验证码登录的校验方式及自动登录的解决方案的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。