zoukankan      html  css  js  c++  java
  • 新浪微博开放平台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:

        直接上代码:

    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就能避免很多错误。

      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重新保存下,下面是代码:

    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();
        }

      4、获取登录用户信息:

      步骤简单和以上几个请求方式也一样,主要是要将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()
    {
        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/

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

  • 相关阅读:
    解决Could not load file or assembly CefSharp.Core.dll的问题
    操作AppConfig.xml中AppSettings对应值字符串
    SqlServer根据时段统计数据
    Jquery Validation 多按钮,多表单,分组验证
    HDU 4630 No Pain No Game 线段树 和 hdu3333有共同点
    二叉查找树模板
    五边形数定理
    HDU 4651 Partition 整数划分,可重复情况
    CSU 1114 平方根大搜索 java大数
    hdu 4869 Turn the pokers
  • 原文地址:https://www.cnblogs.com/tianxiang2046/p/3574998.html
Copyright © 2011-2022 走看看