OAuth 2.0 開發完全詳解


 

--------------------------基礎篇-------------------------------

I:OAuth 2.0 概述

首先大家來看看國內新浪跟騰訊這兩大頭對OAuth 2.0是怎么個用官方語言去闡述的:

新浪:OAuth2.0是從2006年開始設計OAuth協議的下一個版本,OAuth2.0同時提供Web,桌面和移動應用程序的支持,並較1.0相比整個授權驗證流程更簡單更安全。也是新浪微博開放平台未來最主要的用戶身份驗證和授權方式。

騰訊:騰訊微博開放平台,是基於騰訊微博系統,為廣大開發者和用戶提供的開放數據分享與傳播平台。

廣大開發者和用戶登錄平台后,就可以使用平台提供的開放API接口,創建應用從微博系統獲取信息,或將新的信息傳播到整個微博系統中,豐富多樣的API接口和應用,加上您的智慧,將創造出無窮的應用和樂趣。

在使用騰訊微博平台提供的API前,您需要做以下兩步工作:

成為開發者,並申請appkey和appsecret
授權獲取accesstoken
Accesstoken是第三方獲得用戶授權的憑證,是第三方訪問api資源的票據。目前,騰訊微博采用Oauth2.0協議對第三方進行授權,相對Oauth1.0來說,Oauth2.0具有更加簡單和安全特點。

老外的介紹鏈接 & 百度百科

相比之下我說一下我個人的理解!OAuth是一種允許你的應用訪問到騰訊微博,新浪微博開放平台上的用戶數據,而且是在不需要取得用戶個人密碼的情況下。所以可以說OAuth 2.0是一個互聯網標准協議(OAuth 2.0基於https)。

image

II:OAuth 2.0在國內支持的授權方式

1.Authorization Code方式(新浪,騰訊都支持)

Authorization Code授權方式是專門提供給第三方WEB應用的。目前國內的新浪微博,騰訊開放平台都支持Authorization Code授權方式,下面我將發布一些圖片讓大家對於這種授權方式有一種更為直觀的了解。

image

進入我的測試站時。如果用戶已經有了新浪微博或騰訊微博的賬戶那么他可以直接點擊下面的鏈接進行跳轉授權驗證。如下圖

image
image
從上圖的地址欄信息可以知道~~用戶的密碼始終沒有對我的第三方應用暴露。

當用戶對我的第三方應用授權了以后,我將可以很輕松地讀取用戶個人信息和發送測試微博。
image
騰訊接口返回的用戶信息

image
新浪微博返回的用戶信息



image
發送的測試微博信息

以上的登陸授權示例就是我推薦使用的Authorization Code授權方式
在這個模式下AccessToken沒有透露在地址欄上~用戶密碼也沒有暴露在我的第三方應用當中!這里可以看出OAuth2.0相比OAuth1.0來說更簡單,更安全(https)

2.Resource Owner Password Credentials方式(新浪支持)

樓主不研究這個,因為這個是新浪提供的。騰訊微博未發現支持這種這么犀利的驗證方式,居然允許第三方應用取得用戶密碼。。。。

3.Implicit Grant方式(新浪,騰訊都支持)

樓主也不研究這個,因為這個方式允許AccessToken暴露在用戶的Url上。

 

III:總結

好了,博主dotNetDR_目前只在Web開發當中運用到OAuth 2.0,所以這個系列往后也只涉及OAuth2.0里面的Authorization Code驗證授權模式,除了它以外的OAuth 2.0其他授權模式各位同學有需要的話請自行研究。

項目代碼截圖
image

 

---------------------------------核心篇-------------------------------------------

I:OAuth 2.0 開發前期准備

天上不會自然掉餡餅讓你輕松地去訪問到人家資源服務器里面的用戶數據資源,所以你需要做的前期開發准備工作就是把AppKey, AppSecret取到手 新浪獲取傳送門騰訊獲取傳送門

這里說一下,在申請AppKey和AppSecret的過程中,新浪和騰訊的申請做法是有區別的。image
在新浪微博的AppKey,AppSecret申請時會驗證你是否擁有域名的所有權


image
而騰訊在這一塊上面則沒有這個要求!

PS:申請成為開放平台開發者時需要上傳身份證電子文件。。。。。

II:為什么不用官方提供的SDK

說到這個我就想吐槽了,這官方的SDK尼瑪的明顯排斥堆擠咋們做.net的啊!~~~
先上新浪支持的SDK:
image


然后在上騰訊支持的SDK:
image
image

文檔資料不全不說,出了問題你還得找人家。所以在這里我也試想過轉戰JS SDK看看~於是又有了如下的悲劇事情發生:

騰訊和新浪的JS SDK都是主推用js彈窗方面的。這樣不太會電腦的用戶使用起來的話,就會覺得你的這個第三方應用會不會是病毒神馬的。
image IE9下彈窗提示


image Chrome下也會提示,所以這個東西是瀏覽器本身機制的問題~所以在帖子里面也得到了准確的答復。


image 稍微設置一下允許彈窗的話就得到上面這個怪異摸樣。。。


而在這里稍微說一下騰訊的OPENJS這個東西!!我個人感覺它想挑戰一下我們開發人員的智商。。。
image這個為什么瀏覽器沒有阻止,完全是在同域的情況下啊~~~TX你這互聯老大連另外整個類似於新浪的獨立域名的工作都沒做好啊!!還在自家的API文檔站上高亮標示起這個OpenJS新秀呀。
image 

不過相比新浪的JS SDK騰訊自家的OpenJS的技術支持做得非常好的。你只要碰到了問題。都有人在線幫你解答。

PS:如果你選用JS SDK的話,那么你的業務邏輯將會以js腳本的形式暴露在客戶端瀏覽器之下。

III:Authorization Code驗證授權模式

基礎知識:
在這里先引用前一篇文章里的示例用圖,然后再接着講解各個部分的相關知識。

1.Resource Server(資源服務器):負責存放服務提供商的用戶數據資源等相關信息。當第三方應用訪問這個資源服務器時,需要提供Access Token否則會提示訪問失敗。所以我們最終的目的就是讓自己開發的第三方Web應用順利地訪問到服務提供商的資源服務器,這才是這個系列文章的最終目的。

2.Authorization Server(驗證授權服務器):負責驗證用戶賬戶名密碼,以及給第三方WEB應用發放Access Token。在這里我上傳兩張圖片為你敘述Authorization Server是什么樣子。
image 新浪的Authorization Server


image
騰訊的Authorization Server

接下來將會繼續講解,這個重要的Access Token(訪問令牌)到底是怎么取得的。

首先作為第三方網站上會顯示一個跳轉到新浪,騰訊授權服務器的<a />超級鏈接。如下圖:
image


下面的圖片將介紹這兩個鏈接的跳轉地址規范:
image

新浪的規范
https://api.weibo.com/oauth2/authorize?client_id={AppKey}&response_type=code&redirect_uri={YourSiteUrl}


騰訊的規范
https://open.t.qq.com/cgi-bin/oauth2/authorize?client_id={AppKey}&response_type=code&redirect_uri={YourSiteUrl}

可以看出新浪和騰訊的規范在此步驟基本一致。

現在講述第2步:image


這時Authorization Server將會跳轉回申請授權驗證的第三方網站~但是會在QueryString內加上一個名為code的參數!例子如下:

騰訊:http://www.mytestsite.com/Tencent.aspx?code=174256357036c9df7db17342f15a9476&openid=45CD8A7A05A0C3E30D8A9AB74EEAA8D1&openkey=98B2964245A2BE2830F7A793E09FE6B0


新浪:http://www.mytestsite.com/Sina.aspx?code=19b83321705c538e0422ba09ac9043a0

從這一步可以看出企鵝與標准脫離的野心逐漸浮現。。。它不僅僅返回code而且還參雜openid&openkey~不知在各位開發者的眼里會不會覺得比較另類?

當我們拿到跳轉回來Url上的QueryString參數code后就可以再次去Authorization Server上請求獲取AccessToken這個重要令牌了!下面接着上圖!!!
image

具體說一下第3步的請求地址規范:
新浪:https://api.weibo.com/oauth2/access_token?client_id={AppKey}&client_secret={AppSecret}&grant_type=authorization_code&redirect_uri={YourSiteUrl}&code={code}


騰訊:https://open.t.qq.com/cgi-bin/oauth2/access_token?client_id={AppKey}&client_secret={AppSecret}&redirect_uri={YourSiteUrl}&grant_type=authorization_code&code={code}

在這一步,騰訊和新浪雙方都完全保持一致,非常慶幸!

第4步,重點來了,授權服務器即將返回Access Token。這是以Response Body的方式,所以說Authorization Code授權方式並沒有對客戶端暴露AccessToken訪問令牌。也是我極力推薦使用的一種授權方式。
image
image
上圖是新浪返回Access Token的內容


image
image
上圖是騰訊返回Access Token的內容

這里需要注意一下第3,4步必須要以http post的方式去發起Request。~

IV:總結

image

-----------------------------------------應用篇------------------------------------

I:訪問資源服務器需要些什么?

訪問資源服務器最最重要的前提條件就是你必須要有Access Token。而關於Access Token的取得原理已經在前面兩篇(第1篇第2篇)隨筆當中有介紹,在這里就略過介紹Access Token的獲取方法了。

首先我們還是先看看新浪、騰訊他們的API文檔上提供的參考內容。

新浪資源服務器API調用規范
image
也就是說新浪目前提供兩種方式去調用API.
第一種是以QueryString參數的形式去調用,例子:
https://api.weibo.com/2/{API接口}?access_token={yourAccessToken}


第二種是往header里添加Authorization:OAuth2 {yourAccessToken}的形式去調用。

 

騰訊資源服務器API調用規范
image
根據騰訊方的文檔資料來看!騰訊目前提供的API調用方法跟新浪的第一種方式類似,但沒有提供類似新浪第二種把Access Token放到Header里面的方式(或許有但是我未能從文檔站上搜索到具體要求)。接着GRD的騰訊又搞了幾個屬於自己的參數如:openid, clientip, oauth_version,微微地創新了一把!關於OpenID騰訊的介紹是OpenID可以唯一標識一個用戶。在同一個應用下,同一個QQ號碼的OpenID是相同的;但在不同應用下,同一個QQ號碼可能有不同的OpenID。另外樓主可以推斷這個oauth_version參數的設計能夠證明目前騰訊接口不是很穩定,到時候估計會鬧2.b/2.c/2.d/2.e/2.*,或者過一定時間后oauth.net推出3.0版本時,可以通過修改oauth_version去支持。

騰訊的例子:
https://open.t.qq.com/api/{API接口}?oauth_consumer_key={AppKey}&access_token={AccessToken}&openid={Openid}&clientip={ClientIP}&oauth_version=2.a&scope=all

在這說一下,騰訊的參數中客戶端ip(clientip)可以不填(博主未確認應用部署上線后是否需要提供,因為應用都在開發期。。。)

 

 

ok,關於騰訊跟新浪的資源服務器API調用規范的重要部分已經介紹完畢了。接下來放送新浪騰訊API列表,因為調用他們的API不單單只是提供Access Token還需要根據接口的說明文檔區確認是GET還是POST那些參數是可選的,那些參數是必選的之類。

新浪API接口地址騰訊API接口地址

附:騰訊接口Q&A新浪接口Q&A

II:訪問資源服務器API示例

首先下載dotNetDR_OAuth2程序集 codeplex下載地址介紹

然后新建一個MVC3的應用程序!將剛剛下載的OAuth2組件引用進來。 (WebForm示例
image

接着在項目代碼文件里添加你的AppKey, AppSecret
image

然后再Home控制器的Index Action加上跳轉到新浪和騰訊微博授權頁面的超級鏈接。

HomeController.cs:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Dynamic;

//引入dotNetDR_OAuth2組件命名空間
using dotNetDR_OAuth2;
using dotNetDR_OAuth2.AccessToken;

namespace dotNetDR_OAuth2.Sample.MVC.Controllers
{
public class HomeController : Controller
{
//獲取新浪、騰訊的IAuthorizationCodeBase接口實例
   private IAuthorizationCodeBase sina = AccessTokenFactory.Create(DefaultAppConfigs.Sina);
private IAuthorizationCodeBase tencent = AccessTokenFactory.Create(DefaultAppConfigs.Tencent);

public ActionResult Index()
{
dynamic model = new ExpandoObject();

//生成主機頭例如:http://www.yourhost.com:8081 (注:默認80端口則不會顯示:80)
var hostPath = AccessTokenToolkit.GenerateHostPath(Request.Url);

//定義授權成功后返回的url地址
    var sinaRedirectUrl = hostPath + Url.Action("Index", "Sina");
var tencentRedirectUrl = hostPath + Url.Action("Index", "Tencent");

//設置超級鏈接
            model.SinaLink = sina.GenerateCodeUrl(sinaRedirectUrl);
            model.TencentLink = tencent.GenerateCodeUrl(tencentRedirectUrl);

return View(model);
}

public ActionResult About()
{
return View();
}
}
}

 

然后Index.cshtml:


@{
ViewBag.Title = "Home Page";
}
@model dynamic

<h2>dotNetDR_OAuth2 微博API訪問組件示例</h2>
<div>
@if (Model != null)
{
<a href="@Model.SinaLink"><img src="http://www.cnblogs.com/Content/Images/xlwb.gif" />新浪微博登陸</a><text>|</text>
<a href="@Model.TencentLink"><img src="http://www.cnblogs.com/Content/Images/txwb.gif" />騰訊微博登陸</a>
}
else
{
<h3>Error: Model沒有值</h3>
}
</div>

image

上圖是效果圖

 

接着我們建立各自的實現:SinaController, TencentController.

新浪部分 - SinaController.cs:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
//導入組件命名空間
using dotNetDR_OAuth2;
using dotNetDR_OAuth2.AccessToken;
using dotNetDR_OAuth2.APIs.Providers.Sina;

namespace dotNetDR_OAuth2.Sample.MVC.Controllers
{
public class SinaController : Controller
{
private IAuthorizationCodeBase _authCode = AccessTokenFactory.Create(DefaultAppConfigs.Sina);

public ActionResult Index(string code)
{
if (Session["accessToken"] == null)
{
if (!string.IsNullOrEmpty(code))
{
var redirectUrl = AccessTokenToolkit.GenerateHostPath(Request.Url) + Url.Action("Index");

var accessToken = _authCode.GetResult(_authCode.GenerateAccessTokenUrl(redirectUrl, code));

if (Session["accessToken"] != null)
{
Session.Remove("accessToken");
}

Session.Add("accessToken", accessToken);

var hasAccessToken = new object();
return View(hasAccessToken);
}
else
{
return GotoIndex();
}
}

return View(new object());
}

public ActionResult ShowUserInfo()
{
if (Session["accessToken"] == null)
{
return GotoIndex();
}

var accessTokenObj = Session["accessToken"] as dynamic;
var uid = accessTokenObj.uid;
var accessToken = accessTokenObj.access_token;

var model = SinaApi.CallGet("users/show.json?uid=" + uid, accessToken);

SinaError err;

if (!SinaApi.HasError(model, out err))
{
return View(model);
}
else
{
Session["err"] = err;
return RedirectToAction("Error");
}
}

public ActionResult PublishMsg()
{
if (Session["accessToken"] == null)
{
return GotoIndex();
}

var accessTokenObj = Session["accessToken"] as dynamic;
var uid = accessTokenObj.uid;
var accessToken = accessTokenObj.access_token;

var msg = "Time: " + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss.fffff") + ": 這是一條來自dotNetDR_OAuth2組件發出的1條測試微博信息!";
var formData = new Dictionary<string, string>();
formData.Add("status", Server.UrlEncode(msg));

SinaError err;

var result = SinaApi.CallPost("statuses/update.json", accessToken, formData);
if (!SinaApi.HasError(result, out err))
{
return View();
}
else
{
Session["err"] = err;
return RedirectToAction("Error");
}
}

public ActionResult Error()
{
var err = Session["err"] as SinaError;

return View(err);
}


#region NonAction
[NonAction]
private ActionResult GotoIndex()
{
return RedirectToAction("Index", "Home");
}
#endregion
}
}

 

Index.cshtml:


@{
ViewBag.Title = "Index";
}

@model object

<h2>操作</h2>
<p>@Html.ActionLink("返回", "Index", "Home")</p>
@if (Model != null)
{
@Html.ActionLink("顯示用戶信息", "ShowUserInfo") <text> | </text>
@Html.ActionLink("發送測試微博", "PublishMsg")
}

 

PublishMsg.cshtml:


@{
ViewBag.Title = "PublishMsg";
}

<h2>發送成功</h2>

 

ShowUserInfo.cshtml:


@{
ViewBag.Title = "ShowUserInfo";
}

<h2>用戶:@Model.screen_name</h2>
<p>
用戶UID: @Model.id<br />
用戶昵稱: @Model.screen_name<br />
友好顯示名稱: @Model.name<br />
用戶所在地區ID: @Model.province<br />
用戶所在城市ID: @Model.city<br />
用戶所在地: @Model.location<br />
用戶描述: @Model.description<br />
用戶博客地址: @Model.url<br />
用戶頭像地址: @Model.profile_image_url @MvcHtmlString.Create(string.Format("<img src='{0}' />", Model.profile_image_url))<br />
用戶的個性化域名: @Model.domain<br />
性別(m:男、f:女、n:未知): @Model.gender<br />
粉絲數: @Model.followers_count<br />
關注數: @Model.friends_count<br />
微博數: @Model.statuses_count<br />
收藏數: @Model.favourites_count<br />
創建時間: @Model.created_at<br />
當前登錄用戶是否已關注該用戶: @Model.following<br />
是否允許所有人給我發私信: @Model.allow_all_act_msg<br />
是否允許帶有地理信息: @Model.geo_enabled<br />
是否是微博認證用戶,即帶V用戶: @Model.verified<br />
是否允許所有人對我的微博進行評論: @Model.allow_all_comment<br />
用戶大頭像地址: @Model.avatar_large @MvcHtmlString.Create(string.Format("<img src='{0}' />", @Model.avatar_large))<br />
認證原因: @Model.verified_reason<br />
該用戶是否關注當前登錄用戶: @Model.follow_me<br />
用戶的在線狀態,0:不在線、1:在線: @Model.online_status<br />
用戶的互粉數: @Model.bi_followers_count<br />
</p>

 

Error.cshtml:


@{
ViewBag.Title = "Error";
}

@model dotNetDR_OAuth2.APIs.Providers.Sina.SinaError

<h2>Error</h2>
<p>
error_code: @Model.error_code<br />
error: @Model.error<br />
request: @Model.request<br />
</p>

 

 

 

騰訊部分 - TencentController.cs:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

using dotNetDR_OAuth2;
using dotNetDR_OAuth2.AccessToken;
using dotNetDR_OAuth2.APIs.Providers.Tencent;

namespace dotNetDR_OAuth2.Sample.MVC.Controllers
{
public class TencentController : Controller
{
private IAuthorizationCodeBase _authCode = AccessTokenFactory.Create(DefaultAppConfigs.Tencent);

//
// GET: /Tencent/
public ActionResult Index(string code, string openid, string openkey)
{
if (Session["accessToken"] == null)
{
if (!string.IsNullOrEmpty(code))
{
var redirectUrl = AccessTokenToolkit.GenerateHostPath(Request.Url) + Url.Action("Index");

var accessToken = _authCode.GetResult(_authCode.GenerateAccessTokenUrl(redirectUrl, code));

if (Session["accessToken"] != null)
{
Session.Remove("accessToken");
}

accessToken.openid = openid; //注意GRD騰訊自家的微創新
accessToken.openkey = openkey; //注意GRD騰訊自家的微創新

Session.Add("accessToken", accessToken);

var hasAccessToken = new object();
return View(hasAccessToken);
}
else
{
return GotoIndex();
}
}

return View(new object());
}

public ActionResult ShowUserInfo()
{
if (Session["accessToken"] == null)
{
return GotoIndex();
}

var accessTokenObj = Session["accessToken"] as dynamic;
var uid = accessTokenObj.name;
var accessToken = accessTokenObj.access_token;
var openid = accessTokenObj.openid;

var model = TencentApi.CallGet("user/info?format=json", accessToken, openid);

TencentError err;

if (!TencentApi.HasError(model, out err))
{
var realModel = model.data;
return View(realModel);
}
else
{
Session["err"] = err;
return RedirectToAction("Error");
}
}

public ActionResult PublishMsg()
{
if (Session["accessToken"] == null)
{
return GotoIndex();
}

var accessTokenObj = Session["accessToken"] as dynamic;
var uid = accessTokenObj.name;
var accessToken = accessTokenObj.access_token;
var openid = accessTokenObj.openid;

var msg = "Time: " + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss.fffff") + ": 這是一條來自dotNetDR_OAuth2組件發出的1條測試微博信息!";
var formData = new Dictionary<string, string>();
formData.Add("content", Server.UrlEncode(msg));

TencentError err;

var result = TencentApi.CallPost("t/add?format=json", accessToken, openid, formData);
if (!TencentApi.HasError(result, out err))
{
return View();
}
else
{
Session["err"] = err;
return RedirectToAction("Error");
}
}

public ActionResult Error()
{
var err = Session["err"] as TencentError;

return View(err);
}

#region NonAction
[NonAction]
private ActionResult GotoIndex()
{
return RedirectToAction("Index", "Home");
}
#endregion
}
}

 

Index.cshtml:


@{
ViewBag.Title = "Index";
}
@model object

<h2>操作</h2>
<p>@Html.ActionLink("返回", "Index", "Home")</p>
@if (Model != null)
{
@Html.ActionLink("顯示用戶信息", "ShowUserInfo") <text> | </text>
@Html.ActionLink("發送測試微博", "PublishMsg")
}

 

PublishMsg.cshtml:


@{
ViewBag.Title = "PublishMsg";
}

<h2>發送成功</h2>

 

ShowUserInfo.cshtml:


@{
ViewBag.Title = "ShowUserInfo";
}

<h2>用戶昵稱: @Model.nick</h2>
<p>
出生天: @Model.birth_day <br />
出生月: @Model.birth_month <br />
出生年: @Model.birth_year <br />
城市id: @Model.city_code <br />
國家id: @Model.country_code <br />
郵箱: @Model.email <br />
聽眾數: @Model.fansnum <br />
收藏數: @Model.favnum <br />
頭像url: @Model.head @MvcHtmlString.Create(string.Format("<img src=\"{0}/50\" />", @Model.head)) <br />
家鄉所在城市id: @Model.homecity_code <br />
家鄉所在國家id: @Model.homecountry_code <br />
個人主頁: @Model.homepage <br />
家鄉所在省id: @Model.homeprovince_code <br />
家鄉所在城鎮id: @Model.hometown_code <br />
收聽的人數: @Model.idolnum <br />
行業id: @Model.industry_code <br />
個人介紹: @Model.introduction <br />
是否企業機構: @Model.isent <br />
是否在當前用戶的黑名單中,0-不是,1-是: @Model.ismyblack <br />
是否是當前用戶的聽眾,0-不是,1-是: @Model.ismyfans <br />
是否是當前用戶的偶像,0-不是,1-是: @Model.ismyidol <br />
是否實名認證,0-老用戶,1-已實名認證,2-未實名認證: @Model.isrealname <br />
是否認證用戶: @Model.isvip <br />
所在地: @Model.location <br />
互聽好友數: @Model.mutual_fans_num <br />
用戶帳戶名: @Model.name <br />
用戶唯一id,與name相對應: @Model.openid <br />
地區id: @Model.province_code <br />
注冊時間: @Model.regtime <br />
是否允許所有人給當前用戶發私信,0-僅有偶像,1-名人+聽眾,2-所有人: @Model.send_private_flag <br />
用戶性別,1-男,2-女,0-未填寫: @Model.sex <br />
發表的微博數: @Model.tweetnum <br />
認證信息: @Model.verifyinfo <br />
</p>

 

Error.cshtml:


@{
ViewBag.Title = "Error";
}
@model dotNetDR_OAuth2.APIs.Providers.Tencent.TencentError

<h2>Error</h2>
<p>
ret: @Model.ret<br />
errcode: @Model.errcode<br />
msg: @Model.msg<br />
----------------------<br />
errcode=1 無效TOKEN,被吊銷<br />
errcode=2 請求重放<br />
errcode=3 access_token不存在<br />
errcode=4 access_token超時<br />
errcode=5 oauth 版本不對<br />
errcode=6 oauth 簽名方法不對<br />
errcode=7 參數錯<br />
errcode=8 處理失敗<br />
errcode=9 驗證簽名失敗<br />
errcode=10 網絡錯誤<br />
errcode=11 參數長度不對<br />
errcode=12 處理失敗<br />
errcode=13 處理失敗<br />
errcode=14 處理失敗<br />
errcode=15 處理失敗<br />
</p>

 

在這里重復上一下效果圖吧!

image

image

發送微博的效果我就不貼了!!

 

 

這里附上一個各位OAuth開發者或許需要的流程圖(專家請盡情噴小菜)

image

visio文件下載

 

III:dotNetDR_OAuth2 組件介紹

在上一節里面的代碼!大家都可以看到這個組件已經隱藏了System.Net.HttpWebRequest, System.Net.HttpWebResponse這些細節,而且返回的值都是dynamic類型的,這樣一下。我們就僅需要對這新浪或者騰訊的API文檔來逐步調試了,因為博主不可能在組件里把每一個接口返回值得都定義成一個C#類文件:



如果都定義成claas我太累了,所以用.NET 4.0 提供的dynamic算了,更加具體內容我打算另外用一遍隨筆去介紹!!轉載的請聲明及保留好出處!!

組件作者:博客園dotNetDR_ http://www.cnblogs.com/highend/

IV:Access Token的過期時間

新浪

image

 

騰訊

image

 

V:示例項目代碼

注意:當你在測試環境下時,必須要把windows系統的hosts文件添加好具體的域名地址指向你本機,例如博主的:

image

 

 

然后就是需要打開dotNetDR_OAuth2.Sample.MVC.csproj手動更改IIS路徑

image

---------------------------------代碼下載---------------------似乎、好像、可能 下載不了-----------------------------

 ----------結束語------------

本文完全摘自:http://www.cnblogs.com/highend/archive/2012/07/10/oauth2_access_sina_and_tencent_resource_server.html

未刪改。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM