[转载]新浪微博开放平台OAuth授权解决方案(含代码) – 勤劳的渔网工作者 – 博客园.
前几日一位朋友项目中需要使用新浪微博的接口,故和这位朋友一同研究了新浪微博开放平台上面所提供的资料,首先要使用这些接口是需要用户登录并且授权的,新浪微博开放平台其实是提供两种授权方式的,第一种是:OAuth授权方式,第二种是:HTTP普通鉴权方式,我们使用了第一种方式来授权,但是在执行过程中遇到了许多问题,觉得单对新浪微博开放平台还是有一些代表性,所以共享下经验,下面可以下载我的Demo。
OAuth是一种国际授权方式,它不需要用户在第三方应用输入用户名及密码,所以安全性很高,那么在新浪微博开放平台中通过OAuth授权的流程图是这样的:
其实在程序中步骤表现就只有4步:
1、获取Request token。
2、用户认证。
3、获取Access token。
4、获取用户信息。
在处理OAuth授权过程中我也碰到几个在新浪开放平台论坛中常见的几个问题,在这里总结下,在后面讲解中会讲到我的想法和解决办法:
1、requesttoken时callback问题。
2、401错误。
3、403错误。
4、500错误。
5、未经授权错误。
在这里顺便讲一下调用新浪微博接口必须是要申请一个应用的,申请应用成功之后会得到一个App key号和App Secret号,我们也需要通过这两个参数来请求授权,还有就是网上有OAuthBase下载,但是要下对版本,我的Demo中也有,我们的授权主要的代 码是在OAuthBase.cs文件中的。
1、获取Request token:
直接上代码:
01 |
public void getRequestToken() |
03 |
Uri uri = new Uri(requestTokenUri); |
04 |
string nonce = oAuth.GenerateNonce(); |
05 |
string timeStamp = oAuth.GenerateTimeStamp(); |
06 |
string normalizeUrl, normalizedRequestParameters; |
08 |
string sig = oAuth.GenerateSignature(uri, apiKey, apiKeySecret, string .Empty, string .Empty, |
09 |
"GET" , timeStamp, nonce, string .Empty, out normalizeUrl, out normalizedRequestParameters); |
10 |
sig = HttpUtility.UrlEncode(sig); |
12 |
StringBuilder sb = new StringBuilder(uri.ToString()); |
13 |
sb.AppendFormat( "?oauth_consumer_key={0}&" , apiKey); |
14 |
sb.AppendFormat( "oauth_nonce={0}&" , nonce); |
15 |
sb.AppendFormat( "oauth_signature={0}&" , sig); |
16 |
sb.AppendFormat( "oauth_signature_method={0}&" , "HMAC-SHA1" ); |
17 |
sb.AppendFormat( "oauth_timestamp={0}&" , timeStamp); |
18 |
sb.AppendFormat( "oauth_version={0}" , "1.0" ); |
20 |
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(sb.ToString()); |
21 |
HttpWebResponse response = (HttpWebResponse)request.GetResponse(); |
22 |
StreamReader stream = new StreamReader(response.GetResponseStream(), System.Text.Encoding.UTF8); |
23 |
string responseBody = stream.ReadToEnd(); |
26 |
int intOTS = responseBody.IndexOf( "oauth_token=" ); |
27 |
int intOTSS = responseBody.IndexOf( "&oauth_token_secret=" ); |
28 |
Session[ "oauth_token" ] = responseBody.Substring(intOTS + 12, intOTSS - (intOTS + 12)); |
29 |
Session[ "oauth_token_secret" ] = responseBody.Substring((intOTSS + 20), responseBody.Length - (intOTSS + 20)); |
30 |
Response.Redirect(AUTHORIZE + "?oauth_token=" + Session[ "oauth_token" ] + "&oauth_callback=" + Request.Url); |
我在请求Request token的时候遇到了401错误和地址返回错误, 地址返回错误比较好解决,一般都是地址错误,所以我直接用了Request.Url,那么401错误了我出错是在签名 的地方,最开始的OAuthBase文件下载错了,下给最新的就可以了,还有就是在请求参数中的oauth_version参数,有很多值是1.0a,这 样好像是不行的,全部改成1.0就能避免很多错误。
2、用户认证:
在Request token请求成功之后,平台自动跳到登录页面,进行用户认证,认证通过之后平台会将oauth_token和oauth_verifier返回到指定的 callback来,将两个参数保存下来用于请求Access token,在这里如果地址不正确是会报错的。
3、获取Access token:
这个请求的重点还是在签名,必须要将用户认证后返回的oauth_token和oauth_verifier一并签名才能正确,有些OAuthBase中是没有将verifier加入签名当中当时让我好生郁闷,如果这点错了应该会报未经授权或者403错误,请求成功之后需要将oauth_token和oauth_token_secret重新保存下,下面是代码:
01 |
public void getAccessToken( string requestToken, string oauth_verifier) |
03 |
Uri uri = new Uri(ACCESS_TOKEN); |
04 |
string nonce = oAuth.GenerateNonce(); |
05 |
string timeStamp = oAuth.GenerateTimeStamp(); |
06 |
string normalizeUrl, normalizedRequestParameters; |
08 |
string sig = oAuth.GenerateSignature( |
13 |
Session[ "oauth_token_secret" ].ToString(), |
19 |
out normalizedRequestParameters); |
20 |
sig = oAuth.UrlEncode(sig); |
22 |
StringBuilder sb = new StringBuilder(uri.ToString()); |
23 |
sb.AppendFormat( "?oauth_consumer_key={0}&" , apiKey); |
24 |
sb.AppendFormat( "oauth_nonce={0}&" , nonce); |
25 |
sb.AppendFormat( "oauth_timestamp={0}&" , timeStamp); |
26 |
sb.AppendFormat( "oauth_signature_method={0}&" , "HMAC-SHA1" ); |
27 |
sb.AppendFormat( "oauth_version={0}&" , "1.0" ); |
28 |
sb.AppendFormat( "oauth_signature={0}&" , sig); |
29 |
sb.AppendFormat( "oauth_token={0}&" , requestToken); |
30 |
sb.AppendFormat( "oauth_verifier={0}" , oauth_verifier); |
32 |
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(sb.ToString()); |
33 |
HttpWebResponse response = (HttpWebResponse)request.GetResponse(); |
34 |
StreamReader stream = new StreamReader(response.GetResponseStream(), System.Text.Encoding.UTF8); |
35 |
string responseBody = stream.ReadToEnd(); |
38 |
int intOTS = responseBody.IndexOf( "oauth_token=" ); |
39 |
int intOTSS = responseBody.IndexOf( "&oauth_token_secret=" ); |
40 |
int intUser = responseBody.IndexOf( "&user_id=" ); |
41 |
Session[ "oauth_token" ] = responseBody.Substring(intOTS + 12, intOTSS - (intOTS + 12)); |
42 |
Session[ "oauth_token_secret" ] = responseBody.Substring((intOTSS + 20), intUser - (intOTSS + 20)); |
43 |
Session[ "User_Id" ] = responseBody.Substring((intUser + 9), responseBody.Length - (intUser + 9)); |
4、获取登录用户信息:
步骤简单和以上几个请求方式也一样,主要是要将oauth_token和oauth_token_secret加入签名,下面是代码:
01 |
public void verify_credentials() |
04 |
string nonce = oAuth.GenerateNonce(); |
05 |
string timeStamp = oAuth.GenerateTimeStamp(); |
06 |
string normalizeUrl, normalizedRequestParameters; |
08 |
string sig = oAuth.GenerateSignature( |
12 |
Session[ "oauth_token" ].ToString(), |
13 |
Session[ "oauth_token_secret" ].ToString(), |
19 |
out normalizedRequestParameters); |
20 |
sig = HttpUtility.UrlEncode(sig); |
21 |
StringBuilder sb = new StringBuilder(uri.ToString()); |
22 |
sb.AppendFormat( "?oauth_consumer_key={0}&" , apiKey); |
23 |
sb.AppendFormat( "oauth_nonce={0}&" , nonce); |
24 |
sb.AppendFormat( "oauth_timestamp={0}&" , timeStamp); |
25 |
sb.AppendFormat( "oauth_signature_method={0}&" , "HMAC-SHA1" ); |
26 |
sb.AppendFormat( "oauth_version={0}&" , "1.0" ); |
27 |
sb.AppendFormat( "oauth_signature={0}&" , sig); |
28 |
sb.AppendFormat( "oauth_token={0}&" , Session[ "oauth_token" ].ToString()); |
29 |
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(sb.ToString()); |
30 |
HttpWebResponse response = (HttpWebResponse)request.GetResponse(); |
31 |
StreamReader stream = new StreamReader(response.GetResponseStream(), System.Text.Encoding.UTF8); |
32 |
string responseBody = stream.ReadToEnd(); |
35 |
Session[ "responseBody" ] = responseBody; |
到这里你可以获取用户的个人信息,那么OAuth授权也就成功,其实步骤是比较简单的,主要要注意的就是签名,签名不正确一定是通过不了的,还有就是一些 细节,如地址,版本号,请求方式这些细心点就能避免,由于时间原因这里讲的比较简单,希望大家互相交流下,这里是Demo:SinaOAuthSinaOAuth