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/

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

  • 相关阅读:
    leetcode231 2的幂 leetcode342 4的幂 leetcode326 3的幂
    leetcode300. Longest Increasing Subsequence 最长递增子序列 、674. Longest Continuous Increasing Subsequence
    leetcode64. Minimum Path Sum
    leetcode 20 括号匹配
    算法题待做
    leetcode 121. Best Time to Buy and Sell Stock 、122.Best Time to Buy and Sell Stock II 、309. Best Time to Buy and Sell Stock with Cooldown 、714. Best Time to Buy and Sell Stock with Transaction Fee
    rand7生成rand10,rand1生成rand6,rand2生成rand5(包含了rand2生成rand3)
    依图
    leetcode 1.Two Sum 、167. Two Sum II
    从分类,排序,top-k多个方面对推荐算法稳定性的评价
  • 原文地址:https://www.cnblogs.com/tianxiang2046/p/3574998.html
Copyright © 2011-2022 走看看