版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
【移動(dòng)應(yīng)用開(kāi)發(fā)技術(shù)】ASP.NET怎樣實(shí)現(xiàn)QQ、微信、新浪微博OAuth2.0授權(quán)登錄
在下給大家分享一下ASP.NET怎樣實(shí)現(xiàn)QQ、微信、新浪微博OAuth2.0授權(quán)登錄,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!實(shí)現(xiàn)QQ、微信、新浪微博OAuth3.0授權(quán)登錄的示例,主要就是GET、POST遠(yuǎn)程接口,返回相應(yīng)的數(shù)據(jù),這里列出相關(guān)的代碼,供大家參考。不管是騰訊還是新浪,查看他們的API,PHP都是有完整的接口,但對(duì)C#支持似乎都不是那么完善,都沒(méi)有,騰訊是完全沒(méi)有,新浪是提供第三方的,而且后期還不一定升級(jí),NND,用第三方的動(dòng)輒就一個(gè)類(lèi)庫(kù),各種配置還必須按照他們約定的寫(xiě),煩而且亂,索性自己寫(xiě),后期的擴(kuò)展也容易,看過(guò)接口后,開(kāi)始以為很難,參考了幾個(gè)源碼之后發(fā)現(xiàn)也不是那么難,無(wú)非是GET或POST請(qǐng)求他們的接口獲取返回值之類(lèi)的,話不多說(shuō),這里只提供幾個(gè)代碼共參考,拋磚引玉了。。。我這個(gè)寫(xiě)法的特點(diǎn)是,用到了Session,使用對(duì)象實(shí)例化之后調(diào)用Login()跳轉(zhuǎn)到登錄頁(yè)面,在回調(diào)頁(yè)面調(diào)用Callback()執(zhí)行之后,可以從Session也可以寫(xiě)?yīng)毩⒌暮瘮?shù)(如:GetOpenID())中獲取access_token或用戶的唯一標(biāo)識(shí),以方便做下一步的操作。所謂綁定就是把用戶的唯一標(biāo)識(shí)取出,插入數(shù)據(jù)庫(kù),和帳號(hào)綁定起來(lái)。1.首先是所有OAuth類(lèi)的基類(lèi),放一些需要公用的方法public
abstract
class
BaseOAuth
{
public
HttpRequest
Request
=
HttpContext.Current.Request;
public
HttpResponse
Response
=
HttpContext.Current.Response;
public
HttpSessionState
Session
=
HttpContext.Current.Session;
public
abstract
void
Login();
public
abstract
string
Callback();
#region
內(nèi)部使用函數(shù)
///
<summary>
///
生成唯一隨機(jī)串防CSRF攻擊
///
</summary>
///
<returns></returns>
protected
string
GetStateCode()
{
Random
rand
=
new
Random();
string
data
=
DateTime.Now.ToString("yyyyMMddHHmmssffff")
+
rand.Next(1,
0xf423f).ToString();
MD5CryptoServiceProvider
md5
=
new
MD5CryptoServiceProvider();
byte[]
md5byte
=
md5.ComputeHash(UTF8Encoding.Default.GetBytes(data));
return
BitConverter.ToString(md5byte).Replace("-",
"");
}
///
<summary>
///
GET請(qǐng)求
///
</summary>
///
<param
name="url"></param>
///
<returns></returns>
protected
string
GetRequest(string
url)
{
HttpWebRequest
httpWebRequest
=
System.Net.WebRequest.Create(url)
as
HttpWebRequest;
httpWebRequest.Method
=
"GET";
httpWebRequest.ServicePoint.Expect100Continue
=
false;
StreamReader
responseReader
=
null;
string
responseData;
try
{
responseReader
=
new
StreamReader(httpWebRequest.GetResponse().GetResponseStream());
responseData
=
responseReader.ReadToEnd();
}
finally
{
httpWebRequest.GetResponse().GetResponseStream().Close();
responseReader.Close();
}
return
responseData;
}
///
<summary>
///
POST請(qǐng)求
///
</summary>
///
<param
name="url"></param>
///
<param
name="postData"></param>
///
<returns></returns>
protected
string
PostRequest(string
url,
string
postData)
{
HttpWebRequest
httpWebRequest
=
System.Net.WebRequest.Create(url)
as
HttpWebRequest;
httpWebRequest.Method
=
"POST";
httpWebRequest.ServicePoint.Expect100Continue
=
false;
httpWebRequest.ContentType
=
"application/x-www-form-urlencoded";
//寫(xiě)入POST參數(shù)
StreamWriter
requestWriter
=
new
StreamWriter(httpWebRequest.GetRequestStream());
try
{
requestWriter.Write(postData);
}
finally
{
requestWriter.Close();
}
//讀取請(qǐng)求后的結(jié)果
StreamReader
responseReader
=
null;
string
responseData;
try
{
responseReader
=
new
StreamReader(httpWebRequest.GetResponse().GetResponseStream());
responseData
=
responseReader.ReadToEnd();
}
finally
{
httpWebRequest.GetResponse().GetResponseStream().Close();
responseReader.Close();
}
return
responseData;
}
///
<summary>
///
解析JSON
///
</summary>
///
<param
name="strJson"></param>
///
<returns></returns>
protected
NameValueCollection
ParseJson(string
strJson)
{
NameValueCollection
mc
=
new
NameValueCollection();
Regex
regex
=
new
Regex(@"(\s*\""?([^""]*)\""?\s*\:\s*\""?([^""]*)\""?\,?)");
strJson
=
strJson.Trim();
if
(strJson.StartsWith("{"))
{
strJson
=
strJson.Substring(1,
strJson.Length
-
2);
}
foreach
(Match
m
in
regex.Matches(strJson))
{
mc.Add(m.Groups[2].Value,
m.Groups[3].Value);
}
return
mc;
}
///
<summary>
///
解析URL
///
</summary>
///
<param
name="strParams"></param>
///
<returns></returns>
protected
NameValueCollection
ParseUrlParameters(string
strParams)
{
NameValueCollection
nc
=
new
NameValueCollection();
foreach
(string
p
in
strParams.Split('&'))
{
string[]
ps
=
p.Split('=');
nc.Add(ps[0],
ps[1]);
}
return
nc;
}
#endregion
}2.QQ的OAuth類(lèi)public
class
QQOAuth
:
BaseOAuth
{
public
string
AppId
=
ConfigurationManager.AppSettings["OAuth_QQ_AppId"];
public
string
AppKey
=
ConfigurationManager.AppSettings["OAuth_QQ_AppKey"];
public
string
RedirectUrl
=
ConfigurationManager.AppSettings["OAuth_QQ_RedirectUrl"];
public
const
string
GET_AUTH_CODE_URL
=
"/oauth3.0/authorize";
public
const
string
GET_ACCESS_TOKEN_URL
=
"/oauth3.0/token";
public
const
string
GET_OPENID_URL
=
"/oauth3.0/me";
///
<summary>
///
QQ登錄,跳轉(zhuǎn)到登錄頁(yè)面
///
</summary>
public
override
void
Login()
{
//生成唯一隨機(jī)串防CSRF攻擊
string
state
=
GetStateCode();
Session["QC_State"]
=
state;
//state
放入Session
string
parms
=
"?response_type=code&"
+
"client_id="
+
AppId
+
"&redirect_uri="
+
Uri.EscapeDataString(RedirectUrl)
+
"&state="
+
state;
string
url
=
GET_AUTH_CODE_URL
+
parms;
Response.Redirect(url);
//跳轉(zhuǎn)到登錄頁(yè)面
}
///
<summary>
///
QQ回調(diào)函數(shù)
///
</summary>
///
<param
name="code"></param>
///
<param
name="state"></param>
///
<returns></returns>
public
override
string
Callback()
{
string
code
=
Request.QueryString["code"];
string
state
=
Request.QueryString["state"];
//驗(yàn)證state防止CSRF攻擊
if
(state
!=
(string)Session["QC_State"])
{
ShowError("30001");
}
string
parms
=
"?grant_type=authorization_code&"
+
"client_id="
+
AppId
+
"&redirect_uri="
+
Uri.EscapeDataString(RedirectUrl)
+
"&client_secret="
+
AppKey
+
"&code="
+
code;
string
url
=
GET_ACCESS_TOKEN_URL
+
parms;
string
str
=
GetRequest(url);
if
(str.IndexOf("callback")
!=
-1)
{
int
lpos
=
str.IndexOf("(");
int
rpos
=
str.IndexOf(")");
str
=
str.Substring(lpos
+
1,
rpos
-
lpos
-
1);
NameValueCollection
msg
=
ParseJson(str);
if
(!string.IsNullOrEmpty(msg["error"]))
{
ShowError(msg["error"],
msg["error_description"]);
}
}
NameValueCollection
token
=
ParseUrlParameters(str);
Session["QC_AccessToken"]
=
token["access_token"];
//access_token
放入Session
return
token["access_token"];
}
///
<summary>
///
使用Access
Token來(lái)獲取用戶的OpenID
///
</summary>
///
<param
name="accessToken"></param>
///
<returns></returns>
public
string
GetOpenID()
{
string
parms
=
"?access_token="
+
Session["QC_AccessToken"];
string
url
=
GET_OPENID_URL
+
parms;
string
str
=
GetRequest(url);
if
(str.IndexOf("callback")
!=
-1)
{
int
lpos
=
str.IndexOf("(");
int
rpos
=
str.IndexOf(")");
str
=
str.Substring(lpos
+
1,
rpos
-
lpos
-
1);
}
NameValueCollection
user
=
ParseJson(str);
if
(!string.IsNullOrEmpty(user["error"]))
{
ShowError(user["error"],
user["error_description"]);
}
Session["QC_OpenId"]
=
user["openid"];
//openid
放入Session
return
user["openid"];
}
///
<summary>
///
顯示錯(cuò)誤信息
///
</summary>
///
<param
name="code">錯(cuò)誤編號(hào)</param>
///
<param
name="description">錯(cuò)誤描述</param>
private
void
ShowError(string
code,
string
description
=
null)
{
if
(description
==
null)
{
switch
(code)
{
case
"20001":
description
=
"<h3>配置文件損壞或無(wú)法讀取,請(qǐng)檢查web.config</h3>";
break;
case
"30001":
description
=
"<h3>The
state
does
not
match.
You
may
be
a
victim
of
CSRF.</h3>";
break;
case
"50001":
description
=
"<h3>可能是服務(wù)器無(wú)法請(qǐng)求https協(xié)議</h3>可能未開(kāi)啟curl支持,請(qǐng)嘗試開(kāi)啟curl支持,重啟web服務(wù)器,如果問(wèn)題仍未解決,請(qǐng)聯(lián)系我們";
break;
default:
description
=
"<h3>系統(tǒng)未知錯(cuò)誤,請(qǐng)聯(lián)系我們</h3>";
break;
}
Response.Write(description);
Response.End();
}
else
{
Response.Write("<h4>error:<h4>"
+
code
+
"<h4>msg:<h4>"
+
description);
Response.End();
}
}
}3.新浪微博的OAuth類(lèi)public
class
SinaOAuth
:
BaseOAuth
{
public
string
AppKey
=
ConfigurationManager.AppSettings["OAuth_Sina_AppKey"];
public
string
AppSecret
=
ConfigurationManager.AppSettings["OAuth_Sina_AppSecret"];
public
string
RedirectUrl
=
ConfigurationManager.AppSettings["OAuth_Sina_RedirectUrl"];
public
const
string
GET_AUTH_CODE_URL
=
"/oauth3/authorize";
public
const
string
GET_ACCESS_TOKEN_URL
=
"/oauth3/access_token";
public
const
string
GET_UID_URL
=
"/2/account/get_uid.json";
///
<summary>
///
新浪微博登錄,跳轉(zhuǎn)到登錄頁(yè)面
///
</summary>
public
override
void
Login()
{
//生成唯一隨機(jī)串防CSRF攻擊
string
state
=
GetStateCode();
Session["Sina_State"]
=
state;
//state
放入Session
string
parms
=
"?client_id="
+
AppKey
+
"&redirect_uri="
+
Uri.EscapeDataString(RedirectUrl)
+
"&state="
+
state;
string
url
=
GET_AUTH_CODE_URL
+
parms;
Response.Redirect(url);
//跳轉(zhuǎn)到登錄頁(yè)面
}
///
<summary>
///
新浪微博回調(diào)函數(shù)
///
</summary>
///
<returns></returns>
public
override
string
Callback()
{
string
code
=
Request.QueryString["code"];
string
state
=
Request.QueryString["state"];
//驗(yàn)證state防止CSRF攻擊
if
(state
!=
(string)Session["Sina_State"])
{
ShowError("The
state
does
not
match.
You
may
be
a
victim
of
CSRF.");
}
string
parms
=
"client_id="
+
AppKey
+
"&client_secret="
+
AppSecret
+
"&grant_type=authorization_code&code="
+
code
+
"&redirect_uri="
+
Uri.EscapeDataString(RedirectUrl);
string
str
=
PostRequest(GET_ACCESS_TOKEN_URL,
parms);
NameValueCollection
user
=
ParseJson(str);
Session["Sina_AccessToken"]
=
user["access_token"];
//access_token
放入Session
Session["Sina_UId"]
=
user["uid"];
//uid
放入Session
return
user["access_token"];
}
///
<summary>
///
顯示錯(cuò)誤信息
///
</summary>
///
<param
name="description">錯(cuò)誤描述</param>
private
void
ShowError(string
description
=
null)
{
Response.Write("<h3>"
+
description
+
"</h3>");
Response.End();
}
}4.微信的OAuth類(lèi)public
class
WeixinOAuth
:
BaseOAuth
{
public
string
AppId
=
ConfigurationManager.AppSettings["OAuth_Weixin_AppId"];
public
string
AppSecret
=
ConfigurationManager.AppSettings["OAuth_Weixin_AppSecret"];
public
string
RedirectUrl
=
ConfigurationManager.AppSettings["OAuth_Weixin_RedirectUrl"];
public
const
string
GET_AUTH_CODE_URL
=
"/connect/qrconnect";
public
const
string
GET_ACCESS_TOKEN_URL
=
"/sns/oauth3/access_token";
public
const
string
GET_USERINFO_URL
=
"/sns/userinfo";
///
<summary>
///
微信登錄,跳轉(zhuǎn)到登錄頁(yè)面
///
</summary>
public
override
void
Login()
{
//生成唯一隨機(jī)串防CSRF攻擊
string
state
=
GetStateCode();
Session["Weixin_State"]
=
state;
//state
放入Session
string
parms
=
"?appid="
+
AppId
+
"&redirect_uri="
+
Uri.EscapeDataString(RedirectUrl)
+
"&response_type=code&scope=snsapi_login"
+
"&state="
+
state
+
"#wechat_redirect";
string
url
=
GET_AUTH_CODE_URL
+
parms;
Response.Redirect(url);
//跳轉(zhuǎn)到登錄頁(yè)面
}
///
<summary>
///
微信回調(diào)函數(shù)
///
</summary>
///
<param
name="code"></param>
///
<param
name="state"></param>
///
<returns></returns>
public
override
string
Callback()
{
string
code
=
Request.QueryString["code"];
string
state
=
Request.QueryString["state"];
//驗(yàn)證state防止CSRF攻擊
if
(state
!=
(string)Session["Weixin_State"])
{
ShowError("30001");
}
string
parms
=
"?appid="
+
AppId
+
"&secret="
+
AppSecret
+
"&code="
+
code
+
"&grant_type=authorization_code";
string
url
=
GET_ACCESS_TOKEN_URL
+
parms;
string
str
=
GetRequest(url);
NameValueCollection
msg
=
ParseJson(str);
if
(!string.IsNullOrEmpty(msg["errcode"]))
{
ShowError(msg["errcode"],
msg["errmsg"]);
}
Session["Weixin_AccessToken"]
=
msg["access_token"];
//access_token
放入Session
Session["Weixin_OpenId"]
=
msg["openid"];
//access_token
放入Session
return
msg["access_token"];
}
///
<summary>
///
顯示錯(cuò)誤信息
///
</summary>
///
<param
name="code">錯(cuò)誤編號(hào)</param>
///
<param
name="description">錯(cuò)誤描述</param>
private
void
ShowError(string
code,
string
description
=
null)
{
if
(description
==
null)
{
switch
(code)
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 養(yǎng)老院老人康復(fù)理療師考核獎(jiǎng)懲制度
- 【地球課件】地基基礎(chǔ)設(shè)計(jì)理論與荷載
- 九年級(jí)歷史期末試卷答題卡-教案課件-初中歷史九年級(jí)上冊(cè)部編版
- 房屋租賃的合同(2篇)
- 《食品安全和營(yíng)養(yǎng)》課件
- 2025年拉薩貨運(yùn)從業(yè)資格證模擬試題題庫(kù)及答案大全
- 2025年揚(yáng)州貨運(yùn)從業(yè)資格證考些什么內(nèi)容
- 2024年土地承包合同終止后的土地經(jīng)營(yíng)權(quán)租賃協(xié)議6篇
- 中國(guó)古代禮儀文明課件-婚禮
- 2025年沈陽(yáng)經(jīng)營(yíng)性道路客貨運(yùn)輸駕駛員從業(yè)資格考試
- 化學(xué)品使用安全操作規(guī)范技巧技能講座
- 護(hù)理腦梗死小講課
- 數(shù)字華容道+課時(shí)4
- 脫發(fā)演示課件
- 2024年山東濟(jì)南軌道交通集團(tuán)招聘筆試參考題庫(kù)含答案解析
- 雙選會(huì)策劃書(shū)
- 新能源汽車(chē)電氣系統(tǒng)檢修(第2版)高職 全套教學(xué)課件
- 高考小說(shuō)閱讀分類(lèi)導(dǎo)練:詩(shī)化小說(shuō)(知識(shí)導(dǎo)讀+強(qiáng)化訓(xùn)練+答案解析)
- 牛頓第一定律完整版課件
- 區(qū)域經(jīng)濟(jì)學(xué)試題及答案
- 五年級(jí)上冊(cè)英語(yǔ)一課一練-Unit 6 In a nature park課時(shí)(4) 人教PEP(word版含答案)
評(píng)論
0/150
提交評(píng)論