天天看點

C# 網絡程式設計之豆瓣OAuth2.0認證詳解和遇到的各種問題及解決

        最近在幫人弄一個豆瓣api應用,在豆瓣的oauth2.0認證過程中遇到了各種問題,同時自己需要一個個的嘗試與解決,最終完成了豆瓣api的通路.作者這裡就不再吐槽豆瓣的認證文檔了,畢竟人家也不容易.但是作者發現關于豆瓣oauth認證過程的文章非常之少,是以想詳細寫這樣一篇文章友善後面要做同樣東西的人閱讀.希望文章對大家有所幫助,尤其是想做豆瓣api開發的初學者.

        (文章中藍色字表示官方文檔引用,紅色字是可能遇到問題及注意,黑色字是作者叙述)

        它主要是通過google-oauth項目提供的c#語言的oauth庫,在自定義oauth類中有計算簽名值oauth_signature方法,簽名方法hmac-sha1,還有計算時間戳oauth_timestamp等方法,然後在參照doubanoauthbasicsample項目完成它的認證流程,主要方法是getrequesttoken、authorization和getaccesstoken.

        其實,你隻要知道它已經過時,不要在使用該方法即可.下面才是我想講述的具體如何通過c#程式完成豆瓣的oauth認證并通路需要授權的資料.

        使用oauth2.0流程具體如下:(官方文檔)

        1.應用向豆瓣請求授權

        2.豆瓣為使用者顯示一個授權頁面,使用者在此頁面确認是否同意授權

        3.如果使用者同意授權,應用彙擷取到一個通路令牌(access_token),通過此令牌使用者可以通路授權資料

        4.如果通路需要授權的api,請使用https協定,加上access_token的header.

        下面詳細講解

        首先你需要申請api key,在完成申請過程中你需要注意3個值:api key\secret\回調位址.後面的程式需要應用,當使用的時候我會詳細介紹.由于我是桌面用戶端應用,授權流程為native-application flow.

        根據它的具體流程我設計的界面如下圖所示:

C# 網絡程式設計之豆瓣OAuth2.0認證詳解和遇到的各種問題及解決

      擷取authorization_code步驟(官方文檔)

      通過在浏覽器中通路下面位址,來引導使用者授權并擷取authorization_code.

      https://www.douban.com/service/auth2/auth

      參數:

      client_id  必選參數,應用的唯一辨別,對應于apikey

      redirect_uri  必選參數,使用者授權完成後的回調位址,通過回調位址獲得使用者的授權結果.與注冊一緻.

      response_type  必選參數,此值可以為code或者token.在本流程中此值為code

      scope  可選參數,申請權限的範圍,如果不填,則使用預設的scope.如果申請多個scope,使用逗号分隔

      state  可選參數,用來維護請求和回調狀态的附加字元串,授權完成回調時會附加此參數,應用根據此字元串來判斷上下文關系.

      注意:此請求必須是http get方式

      傳回結果:

      當使用者拒絕授權時,浏覽器會重定向到redirect_uri,并附加錯誤資訊

      https://www.example.com/back?error=access_denied

      當使用者同意授權時,浏覽器會重定向到redirect_uri,并附加autorization_code

      https://www.example.com/back?code=9b73a4248

      首先,你需要定義變量如下,這些變量都是我們需要使用的.其中apikey\secret\回調位址填寫你自己的,下面的被我改過不是源資料(擔心丢失)

        然後,點選button1(浏覽)按鈕,同時設計視圖中為webbrowser1控件添加documentcompleted事件(右鍵->屬性->'閃電圖示'事件).同時引用命名空間:using system.web;\using system.net;\using system.io;

        運作結果如下圖所示,填寫完使用者郵箱和密碼,點選授權後擷取autorization_code如下:

C# 網絡程式設計之豆瓣OAuth2.0認證詳解和遇到的各種問題及解決
C# 網絡程式設計之豆瓣OAuth2.0認證詳解和遇到的各種問題及解決

這裡你需要注意的有一下幾點:

        1.為什麼我的回調位址設定為"http://www.baidu.com/"?

         最初我設定的回調位址為自定義的一個網址,但是輸入郵箱和密碼後點選授權,總是http 400錯誤,啥都不能擷取.使用ie浏覽器也是一樣,但是google能擷取.後來經過同學提醒(他做騰訊api,資料多,官方文檔規範)可能回調位址需要能通路的網址,是以改成了百度,并且成功擷取.因為這一步隻需要擷取code值,網址并不關鍵.(可能也有沒考慮到的地方)

        2.你需要知道該程式中必須使用get方法=浏覽可以直接通路.(除設定header,後面講述)

        在程式中我是直接調用webbrowser1.navigate(input);函數通路的,也可以使用get方法通路.get和post的差別是你需要知道的,簡單來說就是get後面給的網址參數顯示,而post是隐式的.

        程式和文檔中說道的采用get的方法,并帶有參數的都是這樣連接配接的.url+?+參數=參數值&參數=參數值...正如擷取code中的url,它通過浏覽器是可以直接通路的.

        3.你可能會遇到的錯誤是113 缺少參數required_parameter_is_missing.

        此時你在設定url時,通過stringbuilder可變字元串增加參數時,需要把所有的必須的參數填寫.同時,注意你的&和?是否正确填寫.你可以參考的官方文檔錯誤報告如下:

        此時,你的第一步擷取code已經完成,接下來是擷取access_token的過程.

        官方文檔接受的擷取access_token如下:

        https://www.douban.com/service/auth2/token

        參數:

       client_id  必選參數,應用的唯一辨別,對應于apikey

        client_sercet 必選參數,應用的唯一辨別,對應于豆瓣secret

        redirect_url 必選參數,使用者授權後的回調位址

        grant_type 必選參數,此值可為authorization_code或者refresh_token,此時為authorization_code

        code 必選參數,上一步中擷取的authorization_code

        注意:此請求必須是http post方式

        傳回結果為json格式資料如下圖所示

        其中你需要注意的是四個地方:

        1.如何使用post方法發送請求擷取應答,這再也不是通過浏覽器就能直接通路的問題.

        2.擷取的json格式資料如何通過c#解析.

        3.可能你的通路不成功,你需要在"我的應用"中添加測試使用者.看看自己的是否添加.

        4.你可能遇到101 錯誤的請求方法,invalid_request_method: get因為你需要采用post方法.

        我講解如何解析json格式的資料,這裡參照很多人可能都使用過的方法.

.net4.5).

        在"解決方案"中滑鼠右鍵引用->添加引用->浏覽->添加該dll.然後添加命名空間using newtonsoft.json.linq;将post方法擷取應答string轉換為json格式轉換指派即可.具體代碼如下,同時post方法發送http請求我是通過自定義函數sendmessage實作的.加載button2(授權)按鈕事件.

運作程式,點選"浏覽"授權成果後在點選"授權"的運作結果如下圖所示:

C# 網絡程式設計之豆瓣OAuth2.0認證詳解和遇到的各種問題及解決

        通過前面的步驟我們已經擷取了access_token資料,那麼怎樣使用它呢?當我看到豆瓣給出的使用官方文檔如下時:

        我很頭痛啊!那麼,怎樣通過c#實作使用access_token通路要授權的資料呢?

        get https://api.douban.com/v2/user/~me

        該url是擷取目前授權使用者資訊的,需要必須先進行api認證授權,傳回的是目前授權使用者資訊.是以,使用它完全可以驗證授權成果後的操作.具體代碼如下:

        運作結果如下圖所示:

C# 網絡程式設計之豆瓣OAuth2.0認證詳解和遇到的各種問題及解決

        不要以為這簡單的幾句代碼就很容易實作了通路資料,其實你需要注意一下幾點:

        1.你可能會遇到1000錯誤 需要權限need_permission?

        那時你需要在通路時設定header,添加-h "authorization: bearer a14afef0f66fcffce3e0fcd2e34f6ff4".采用c#設定标題頭的具體代碼如下:

        request.headers.add("authorization", "bearer " + accesstoken);

        其中你需要注意bearer後面的空格.而且有同學說他在使用網盤認證時,擷取的方法有兩種,一種是設定header,一種是在url後面加上?access_token=值即可.但我測試了下豆瓣隻有設定header可以.

        最後總結下它的具體步驟,其實它就是按照豆瓣的文檔完成的,三個步驟:擷取authorization_code、擷取access_token和使用access_token.你也不能說豆瓣文檔講得不好,其實實質東西它都講述清除了.需要的隻是你自己的探索,可能剛接觸比較新鮮和難,但其實完成後就發現它很簡單.

        希望該文章對大家有所幫助,尤其是想做豆瓣api開發的并且使用c#的,這方面資料比較少,基本都是php和java的.更希望同學能從該文章中學到一下幾個東西:

        1.如何通過官方文檔完成一個東西,可能遇到的問題都需要自己解決,而不是複制粘貼.

        2.如何使用c#網絡程式設計get和post兩種方法http請求并擷取應答.

        3.如何使用c#解析json格式的資料.

        4.如何使用oauth認證api開發,這方面騰訊、新浪等比較完善.

        最後也感謝豆瓣網帶給我很多知識,推薦程式員也看看文學書籍,如《文學回憶錄》和《季羨林 清華園日記》,生活不隻有程式設計啊.如果有錯誤或不足之處,還請海涵.