新浪微博开放平台OAuth受权解决方案(含代码)

 前几日一位朋友项目中须要使用新浪微博的接口,故和这位朋友一同研究了新浪微博开放平台上面所提供的资料,首先要使用这些接口是须要用户登陆而且受权的,新浪微博开放平台实际上是提供两种受权方式的,第一种是:OAuth受权方式,第二种是:HTTP普通鉴权方式,咱们使用了第一种方式来受权,可是在执行过程当中遇到了许多问题,以为单对新浪微博开放平台仍是有一些表明性,因此共享下经验,下面能够下载个人Demo。api

  OAuth是一种国际受权方式,它不须要用户在第三方应用输入用户名及密码,因此安全性很高,那么在新浪微博开放平台中经过OAuth受权的流程图是这样的:安全

  其实在程序中步骤表现就只有4步:微信

                                      一、获取Request token。测试

               二、用户认证。网站

               三、获取Access token。ui

               四、获取用户信息。url

  在处理OAuth受权过程当中我也碰到几个在新浪开放平台论坛中常见的几个问题,在这里总结下,在后面讲解中会讲到个人想法和解决办法:spa

               一、requesttoken时callback问题。code

               二、401错误。orm

               三、403错误。

               四、500错误。

               五、未经受权错误。

  在这里顺便讲一下调用新浪微博接口必须是要申请一个应用的,申请应用成功以后会获得一个App key号和App Secret号,咱们也须要经过这两个参数来请求受权,还有就是网上有OAuthBase下载,可是要下对版本,个人Demo中也有,咱们的受权主要的代码是在OAuthBase.cs文件中的。

  一、获取Request token:

    直接上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public  void  getRequestToken()
     {
         Uri uri = new  Uri(requestTokenUri);
         string  nonce = oAuth.GenerateNonce(); //获取随机生成的字符串,防止攻击
         string  timeStamp = oAuth.GenerateTimeStamp(); //发起请求的时间戳
         string  normalizeUrl, normalizedRequestParameters;
         // 签名
         string  sig = oAuth.GenerateSignature(uri, apiKey, apiKeySecret, string .Empty, string .Empty,
           "GET" , timeStamp, nonce, string .Empty, out  normalizeUrl, out  normalizedRequestParameters);
         sig = HttpUtility.UrlEncode(sig);
         //构造请求Request Token的url
         StringBuilder sb = new  StringBuilder(uri.ToString());
         sb.AppendFormat( "?oauth_consumer_key={0}&" , apiKey);
         sb.AppendFormat( "oauth_nonce={0}&" , nonce);
         sb.AppendFormat( "oauth_signature={0}&" , sig);
         sb.AppendFormat( "oauth_signature_method={0}&" , "HMAC-SHA1" );
         sb.AppendFormat( "oauth_timestamp={0}&" , timeStamp);
         sb.AppendFormat( "oauth_version={0}" , "1.0" );
         //请求Request Token
         HttpWebRequest request = (HttpWebRequest)WebRequest.Create(sb.ToString());
         HttpWebResponse response = (HttpWebResponse)request.GetResponse();
         StreamReader stream = new  StreamReader(response.GetResponseStream(), System.Text.Encoding.UTF8);
         string  responseBody = stream.ReadToEnd();
         stream.Close();
         response.Close();
         int  intOTS = responseBody.IndexOf( "oauth_token=" );
         int  intOTSS = responseBody.IndexOf( "&oauth_token_secret=" );
         Session[ "oauth_token" ] = responseBody.Substring(intOTS + 12, intOTSS - (intOTS + 12));
         Session[ "oauth_token_secret" ] = responseBody.Substring((intOTSS + 20), responseBody.Length - (intOTSS + 20));
         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就能避免不少错误。

 

  二、用户认证:

   在Request token请求成功以后,平台自动跳到登陆页面,进行用户认证,认证经过以后平台会将oauth_token和oauth_verifier返回到指定的callback来,将两个参数保存下来用于请求Access token,在这里若是地址不正确是会报错的。

  三、获取Access token:

     这个请求的重点仍是在签名,必需要将用户认证后返回的oauth_token和oauth_verifier一并签名才能正确,有些OAuthBase中是没有将verifier加入签名当中当时让我好生郁闷,若是这点错了应该会报未经受权或者403错误,请求成功以后须要将oauth_token和oauth_token_secret从新保存下,下面是代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public  void  getAccessToken( string  requestToken, string  oauth_verifier)
     {
         Uri uri = new  Uri(ACCESS_TOKEN);
         string  nonce = oAuth.GenerateNonce();
         string  timeStamp = oAuth.GenerateTimeStamp();
         string  normalizeUrl, normalizedRequestParameters;
         // 签名
         string  sig = oAuth.GenerateSignature(
         uri,
         apiKey,
         apiKeySecret,
         requestToken,
         Session[ "oauth_token_secret" ].ToString(),
         "Get" ,
         timeStamp,
         nonce,
         oauth_verifier,
         out  normalizeUrl,
         out  normalizedRequestParameters);
         sig = oAuth.UrlEncode(sig);
         //构造请求Access Token的url
         StringBuilder sb = new  StringBuilder(uri.ToString());
         sb.AppendFormat( "?oauth_consumer_key={0}&" , apiKey);
         sb.AppendFormat( "oauth_nonce={0}&" , nonce);
         sb.AppendFormat( "oauth_timestamp={0}&" , timeStamp);
         sb.AppendFormat( "oauth_signature_method={0}&" , "HMAC-SHA1" );
         sb.AppendFormat( "oauth_version={0}&" , "1.0" );
         sb.AppendFormat( "oauth_signature={0}&" , sig);
         sb.AppendFormat( "oauth_token={0}&" , requestToken);
         sb.AppendFormat( "oauth_verifier={0}" , oauth_verifier);
         //请求Access Token
         HttpWebRequest request = (HttpWebRequest)WebRequest.Create(sb.ToString());
         HttpWebResponse response = (HttpWebResponse)request.GetResponse();
         StreamReader stream = new  StreamReader(response.GetResponseStream(), System.Text.Encoding.UTF8);
         string  responseBody = stream.ReadToEnd();
         stream.Close();
         response.Close();
         int  intOTS = responseBody.IndexOf( "oauth_token=" );
         int  intOTSS = responseBody.IndexOf( "&oauth_token_secret=" );
         int  intUser = responseBody.IndexOf( "&user_id=" );
         Session[ "oauth_token" ] = responseBody.Substring(intOTS + 12, intOTSS - (intOTS + 12));
         Session[ "oauth_token_secret" ] = responseBody.Substring((intOTSS + 20), intUser - (intOTSS + 20));
         Session[ "User_Id" ] = responseBody.Substring((intUser + 9), responseBody.Length - (intUser + 9));
         verify_credentials();
     }

  四、获取登陆用户信息:

  步骤简单和以上几个请求方式也同样,主要是要将oauth_token和oauth_token_secret加入签名,下面是代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public  void  verify_credentials()
{
     Uri uri = new  Uri( "http://api.t.sina.com.cn/account/verify_credentials.xml" );
     string  nonce = oAuth.GenerateNonce();
     string  timeStamp = oAuth.GenerateTimeStamp();
     string  normalizeUrl, normalizedRequestParameters;
     // 签名
     string  sig = oAuth.GenerateSignature(
     uri,
     apiKey,
     apiKeySecret,
     Session[ "oauth_token" ].ToString(),
     Session[ "oauth_token_secret" ].ToString(),
     "Get" ,
     timeStamp,
     nonce,
     string .Empty,
     out  normalizeUrl,
     out  normalizedRequestParameters);
     sig = HttpUtility.UrlEncode(sig);
     StringBuilder sb = new  StringBuilder(uri.ToString());
     sb.AppendFormat( "?oauth_consumer_key={0}&" , apiKey);
     sb.AppendFormat( "oauth_nonce={0}&" , nonce);
     sb.AppendFormat( "oauth_timestamp={0}&" , timeStamp);
     sb.AppendFormat( "oauth_signature_method={0}&" , "HMAC-SHA1" );
     sb.AppendFormat( "oauth_version={0}&" , "1.0" );
     sb.AppendFormat( "oauth_signature={0}&" , sig);
     sb.AppendFormat( "oauth_token={0}&" , Session[ "oauth_token" ].ToString());
     HttpWebRequest request = (HttpWebRequest)WebRequest.Create(sb.ToString());
     HttpWebResponse response = (HttpWebResponse)request.GetResponse();
     StreamReader stream = new  StreamReader(response.GetResponseStream(), System.Text.Encoding.UTF8);
     string  responseBody = stream.ReadToEnd();
     stream.Close();
     response.Close();
     Session[ "responseBody" ] = responseBody;
}

到这里你能够获取用户的我的信息,那么OAuth受权也就成功,其实步骤是比较简单的,主要要注意的就是签名,签名不正确必定是经过不了的,还有就是一些细节,如地址,版本号,请求方式这些细心点就能避免,因为时间缘由这里讲的比较简单,但愿你们互相交流下,这里是Demo:SinaOAuth

QQ互联,参考网站:http://www.dandanxiaoshuo.com/

关注下面的微信公众帐号进行测试: 扫描一下

相关文章
相关标签/搜索