Friday, June 4, 2010

Yahoo! OAuth導入分享

之前玩了使用第三方廠商導入OpenID,這個方式對於個人使用者來說很足夠了,不過對於公司企業來說,技術還是要掌握在自己手裡,所以又來研究這個Yahoo! OAuth

我就不介紹OAuth的來由了,直接進入正題。

在開始之前,可以先看看OAuth Authorization Model,對於OAuth有一些說明。
Yahoo也提供了線上說明文件OAuth / OpenID Guides可以參考。
如果看著說明文件還是有問題,可以到YDN ForumsY的OAuth區詢問 (因為照Yahoo的說明做一定會有問題XD,有的地方有錯)
再來,就是看下面這張圖去按照流程開始接Yahoo! OAuth。
oauth_graph



STEP 1 Sign Up and Get your API Key


首先,先到這邊申請Yahoo! API Key
https://developer.apps.yahoo.com/dashboard/createKey.html

申請完成後,你會在你的My Projects裡面看到目前沒有Project,所以需要創一個新的Project。

YahooOpenID_01

選擇的時候記得選擇"Open Application for the Yahoo! Homepage and My Yahoo!",我一開始是選"Contacts, Mail, MyBlogLog, Social Directory, Status, Updates, Wreth",不過發現認證過不了,之後重創成第一個選項的Application就可以了。

接下來,到Manage Domains,輸入你要使用Yahoo! OAuth的網域。


YahooOpenID_03

輸入後Yahoo會要你放一個指定名稱的html,放上去後再按Verify Domain去驗證就好。




STEP 2 Get a Request Token


詳細內容請參考Yahoo Doc Get a Request Token這篇。簡單來說,就是對https://api.login.yahoo.com/oauth/v2/get_request_token這個網址用POST或GET的方式(我都用POST)送出下列的參數:

Get a Request Token
參數名稱說明
oauth_consumer_keyProject內的Consumer Key
oauth_nonce一個隨便不重複的字串
oauth_signature_method可為PLAINTEXT或HMAC-SHA1,我都用前者,oauth_signature_method的設定會影響oauth_signature這個參數資料的給法
oauth_signatureProject內的Consumer Secret,如果設為PLAINTEXT的話要在字串最後加上%26
oauth_timestamp填入1970/1/1 00:00至今的秒數,Yahoo可允許正負600秒的差距
oauth_version填入1.0
xoauth_lang_pref語言選項,可不傳此參數
oauth_callback取得Request Token後導向的網址

用使用台灣雅虎登入,語言請設成zh-Hant-TW,如果設zh-TW會變成用中國雅虎。

實際上呼叫的範例如下

https://api.login.yahoo.com/oauth/v2/get_request_token?oauth_consumer_key=dj0yJmk9YTNmSHJiNnh6aEpWJmQ9WVdrOVUyRlFRM0JzTm1zbWNHbzlNVEUxTnpBeE1EYzJNZy0tJnM9Y29uc3VtZXJzZWNyZXQmeD1hMA--&oauth_nonce=e43f20fe645b5d674f2c71e04289d2b05&oauth_signature_method=PLAINTEXT&oauth_signature=714185c632fcc18a2fa9644437ebe77df8916559%26&oauth_timestamp=127563433&oauth_version=1.0&xoauth_lang_pref=en-us&oauth_callback=http://doomdied.brinkster.bet/GetYahooOpenID.aspx

呼叫成功後,會傳回幾個參數(在windows下面除錯請使用類似wget的軟體測試),不過只有oauth_token跟oauth_token_secret這兩個參數是後面認證需要的。




Step 3 Get User Approval


拿到oauth_token後,你必須將使用者導向這個網址,讓使用者用Yahoo的帳號登入認證,相關文件請參考Get User Authorization

https://api.login.yahoo.com/oauth/v2/request_auth?oauth_token=第一步取得的oauth_token

使用者登入並同意讓你的Project拉資料後,會導回在Step 2裡oauth_callback所給的網址,這時候會用QueryString的方式傳回oauth_token跟oauth_verifier這兩個之後會用到的參數。




Step 4 Exchange the Request Token for an Access Token


第三步拿到oauth_token跟oauth_verifier後,需要再取得Access Token才能與Yahoo API溝通,而這個步驟的目的是取得Access Token,相關文件請參考Exchange the Request Token and OAuth Verifier for an Access Token
這個步驟也是使用GET或POST傳值給下面這個位址
https://api.login.yahoo.com/oauth/v2/get_token
參數如下:

Exchange the Request Token for an Access Token
參數名稱說明
oauth_consumer_keyProject內的Consumer Key
oauth_signature_method如Step 2所述,可為PLAINTEXT或HMAC-SHA1
oauth_nonce一個隨便不重複的字串
oauth_signatureProject內的Consumer Secret加上Step 2接到的oauth_token_secret,如果設為PLAINTEXT的話要在Consumer Secret最後加上%26 (*)
oauth_timestamp填入1970/1/1 00:00至今的秒數,Yahoo可允許正負600秒的差距
oauth_verifier填入Step 3使用者認證後導回所傳的oauth_verifier
oauth_version填入1.0
oauth_token填入Step 3使用者認證後導回所傳的oauth_token

*:oauth_signature這邊容易出錯,記得是Consumer Secret接%26接oauth_token_secret的字串 (若設定為PLAINTEXT)

實際上呼叫的範例如下

https://api.login.yahoo.com/oauth/v2/get_token?oauth_consumer_key=dj0yJmk9YTNmSHJiNnh6aEpWJmQ9WVdrOVUyRlFRM0JzTm1zbWNHbzlNVEUxTnpBeE1EYzJNZy0tJnM9Y29uc3VtZXJzZWNyZXQmeD1hMA--&oauth_signature_method=PLAINTEXT&oauth_nonce=e43f20fe645b5d674f2c71e04289d2b05&oauth_signature=714185c632fcc18a2fa9644437ebe77df8916559%26
21a2e43f20fe645b5d674f2c71e04289d2b05352&oauth_timestamp=127563433&oauth_verifier=e3snmk&oauth_version=1.0&oauth_token=khey4pe

呼叫成功後回傳幾個參數,列表如下


Access Token Return
參數名稱說明
oauth_tokenAccess Token,Step 5 或呼叫其他Yahoo! API可用
oauth_token_secret對應Access Token的秘鑰,用於auth_signature,Step 5 也需要用到
oauth_session_handle用於更新Access Token(Step 5)時的認證碼
oauth_expires_inAccess Token有效時間,通常是寫3600(秒)
oauth_authorization_expires_inAccess Token將於何時失效,以timestamp型式顯示
xoauth_yahoo_guidYahoo使用者的唯一識別值,也是本次OAuth的目的

以本次要導入Yahoo OAuth來說,取得xoauth_yahoo_guid就可以識別出玩家了(因為每個yahoo帳號的xoauth_yahoo_guid是不一樣的),所以之後就可以拿這個值去做其他的運用了,不過為了完整,我還是把下面Step 5也打完。




Step 5 Refresh the Access Token


在Step 4 取得的Access Token可用於語其他Yahoo! API溝通,但是這個Access Token是有時間性的,超過了時間後就無法使用,所以要用Step 5的功能去更新Access Token,相關文件請見Refresh the Access Token

這個步驟也是使用GET或POST傳值給下面這個位址
https://api.login.yahoo.com/oauth/v2/get_token
參數如下:

Refresh the Access Token
參數名稱說明
oauth_nonce一個隨便不重複的字串
oauth_consumer_keyProject內的Consumer Key
oauth_signature_method如Step 2所述,可為PLAINTEXT或HMAC-SHA1
oauth_signatureProject內的Consumer Secret加上Step 4接到的oauth_token_secret,如果設為PLAINTEXT的話要在Consumer Secret最後加上%26 (*)
oauth_timestamp填入1970/1/1 00:00至今的秒數,Yahoo可允許正負600秒的差距
oauth_version填入1.0
oauth_token填入Step 4所接到的oauth_token(Access Token) (**)
oauth_session_handle填入Step 4所接到的oauth_session_handle

*:文件上對於oauth_signature此欄的說明"The concatenated Shared Secret (Consumer Secret) and Token Secret separated by an "&" character."有誤,實際上不用加上"&",而是與Step 4一樣,Consumer Secret字串後接上%26再接上Step 4所收的oauth_token_secret。
**:這邊填入的oauth_token是Step 4傳回時所收的很長那一串oauth_token(Access Token)

成功後獲得的回傳結構與Step 4 一樣,這邊就不在贅述。



The End


這次弄Yahoo! OAuth其實花了我不少時間,雖然後來覺得資料還蠻詳細的,不過光要找到怎麼開始就找了很久,開始後的除錯也弄得很頭大,還好後來用了wget才看的到錯誤碼,在windows平台上用久了,真的不怎麼容易上手這個。

然後Yahoo OAuth的文件雖然寫的蠻清楚的,但是有些細節還是很容易讓人搞糊塗,看看論壇上的問題幾乎都是我也遇到過的,希望把這些東西寫出來之後,可以讓有需要的人節省一些時間,我估計可以省下九成除錯浪費的時間XD

77 comments:

  1. 感謝你的這篇教學,終於將OAuth給試成功了.雖然我還是花了三天在試,但如果沒有你的說明,我將會花更長的時間學習.

    Thanks!!

    ReplyDelete
  2. 恭喜你,我當初也是一直卡關,花了很久的時間才試出來的,所以特別分享出來。

    其實我也有寫Yahoo OpenID的導入,只是有一步網站認證一直有問題,雖然OpenID可以用,可是會有警告很不爽,所以還沒貼出來,等我有空去解掉再貼出來:P

    ReplyDelete
  3. 卡在驗證 一直驗不過 真討厭

    ReplyDelete
  4. 可以說一下是哪一步嗎 ?

    ReplyDelete
  5. 放一個指定名稱的html,放上去後再按Verify Domain去驗證就好。(你文章提及的這個部份)。 我猜原因是我使用的那家虛擬主機的設定(智邦 linux php4),讓驗證過不了。

    ReplyDelete
  6. 可以把網址跟檔名用email寄給我測測看嗎 ? 感覺上應該是可以過的

    ReplyDelete
  7. Hi
    我有照您的做法去申請
    但選第一個選項後按continue會停留在同個頁面
    選第2個選項則一直出現API Key Creation Failed
    請問您有遇過這樣的問題嗎

    ReplyDelete
  8. to kon :
    我沒有遇過這個問題耶
    如果換瀏覽器也一樣的話,可以寫信問問yahoo
    因為我之前在用yahoo的服務也常遇到些奇怪的類似問題

    ReplyDelete
  9. 好的,多謝啦~有下文再貼回這,免得有別人遇到跟我一樣的情況卻無解

    ReplyDelete
  10. Dear All
    關於[API Key Creation Failed]
    是因為時區要變更成US Yahoo才能申請,
    可以參考這個
    http://patw.idv.tw/blog/archives/242

    不過我想請問各位大大,就是我在
    STEP 2 Get a Request Token
    的動作,送出資料,回應都是
    401未經授權,這是為什麼?有沒有人知道呢?

    ReplyDelete
  11. 我也有用wget,都是寫認證失敗...= =放在這邊

    ReplyDelete
  12. wget裡面應該會有比較詳細的錯誤資訊,找看看吧

    ReplyDelete
  13. 感謝,後來有看到
    WWW-Authenticate: OAuth oauth_problem=consumer_key_rejected
    這個錯誤,原來要將權限打開如下, 選擇“Private user data selected below ……”,同时將Delicious選“Read/Write”。

    ReplyDelete
  14. wget 可以參考我之前寫的這篇
    http://www.died.tw/2010/05/wget-troubleshooting.html
    我有跟你遇過一樣的錯誤XD

    ReplyDelete
  15. 首先感謝版主分享的文章~~~我成功取得guid了

    可是...問題來了~~~~
    我用無名的api(http://tw.developer.yahoo.com/wretch/api.php)
    所提的方法~~沒有一個可以成功取的資料耶....
    就連不需要guid的 方法ex: http://wretch.yahooapis.com/v1/siteAlbumCategories
    都沒辦法取得耶....請問大大有解嗎??

    再次感謝

    ReplyDelete
  16. shin :
    抱歉因為都沒開信箱,所以很晚才回
    請問你的guid是指request token還是access token呢 ?

    ReplyDelete
  17. 我指的是"Access Token Return" 的xoauth_yahoo_guid

    謝謝您喔 我已經看你的文章(關於yahoo api)2天了~~受益良多 ^^

    ReplyDelete
  18. shih :
    據我所知,只拿到user的guid是不夠的,呼叫yahoo api有必需的參數要傳,無名API也一樣(不過他沒寫清楚)
    需要那些參數,你可以參考這篇
    http://developer.yahoo.com/oauth/guide/oauth-make-request.html
    (上面那篇打錯字XD)

    ReplyDelete
  19. 有~~剛好我早上有試出來了~~~而且有補充一些東西在"關於yahoo api"這篇文章,真的太感謝您了~~有更進一步了!!


    ps. 我有提供問題在"關於yahoo api"這篇的留言..希望大大可以協助~~~

    ReplyDelete
  20. 我回啦~~ 抱歉很久沒玩這塊
    記憶有點模糊

    ReplyDelete
  21. 感謝大大詳細的教學分享文,小弟目前有遇到個問題
    我在Get a Request Token的步驟有成功,但是網頁卻沒有導向oauth_callback,不知道問題出在那邊XD,有望大大的指導,萬分感激

    ReplyDelete
  22. Step 3 Get User Approval

    拿到oauth_token後,你必須將使用者導向這個網址,讓使用者用Yahoo的帳號登入認證,相關文件請參考Get User Authorization

    拿到token後就直接再導到上面說的地方吧。

    ReplyDelete
  23. 大大您好:這個地方我不太了解,我該怎麼導向那個網址呢?當我用post到api.login.yahoo.com/oauth/v2/get_request_token?oauth_nonce=頁後,只得到了oauth_token=kmpfc7f&oauth_token_secret=***&oauth_expires_in=3600&...(略),拿到token後要如何導過去呢?

    ReplyDelete
  24. 取得token後,redirect到下面這網址應該就可以啦
    https://api.login.yahoo.com/oauth/v2/request_auth?oauth_token=第一步取得的oauth_token

    ReplyDelete
  25. 大大您好:我知道下一步是redirect到https://api.login.yahoo.com/oauth/v2/request_auth?oauth_token=oauth_token,但是他畫面是停在https://api.login.yahoo.com/oauth/v2/get_request_token?,我該如何redirect呢?

    ReplyDelete
  26. 我送出後會是這樣的畫面,可請大大幫我看一下嗎
    http://www.he-kang168.com/api.php

    ReplyDelete
  27. 你丟到https://api.login.yahoo.com/oauth/v2/get_request_token後取得值就不用管他了,直接向下一個步驟要資料就好。

    ReplyDelete
  28. 請問大大您說不用管他?但我該如何把值抓出來並redirect到下一個步驟呢?

    ReplyDelete
  29. 我的作法是
    HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create("Step2的連結");
    myReq.Method = "POST";
    HttpWebResponse myRes = (HttpWebResponse)myReq.GetResponse();
    如果有取到oauth_token,再redirect
    前面取oauth_token的時候頁面並不會被導走

    ReplyDelete
  30. 感謝大大熱心回覆,小弟已解決這個步驟,真的是萬分感激^^,接著挑戰後續動作,再次謝謝大大。

    ReplyDelete
  31. 大大您好:不好意思,小弟又來請教了,我已完成OAuth 驗證,但是後面應用的部份小弟看不太懂,例如這個yahoo拍賣http://tw.developer.yahoo.com/auction/api.php,我要取得拍賣代號。他上面的範例範例 Response有show出使用者的auid,但是在說明部份卻沒有說明要丟那些參數進去?,上面只說明了format參數,頭痛…

    ReplyDelete
  32. 台灣yahoo的教學寫得不好,你可以參考其他api的參數試試http://developer.yahoo.com/answers/V1/getByUser.html

    ReplyDelete
  33. 請問大大,我在OAuth 驗證後得到的oauth_token、&oauth_token_secret、&oauth_session_handle、&oauth_authorization_expires_in、&xoauth_yahoo_guid這些值,後面都沒有作用了嗎?

    ReplyDelete
  34. 大大不好意思,我照著oauth guide的Chapter 5,但最後結果出會現application/x-www-form-urlencoded not supported with OAuth,不知道該如何解決呢?測試頁http://www.he-kang168.com/post.php

    ReplyDelete
  35. 他說他不支援Url Encode,你可能有的地方把參數encode過了,檢查一下吧。

    ReplyDelete
  36. 好奇怪,但是我沒有encode過任何參數說@@

    ReplyDelete
  37. This comment has been removed by the author.

    ReplyDelete
  38. 我發現我使用的mb_parse_str會將字串encode,感謝大大,小弟再研究看看

    ReplyDelete
  39. 大大您好:小弟有改過來,但是出現一樣的訊息=_=

    ReplyDelete
  40. 大大真不好意思,小弟又來請教了,我後來改用連結的方式,但是xml裡出錯signature_invalid,請問這一步的signature格式為何呢?method只能使用HMAC-SHA1,但是signature卻出現錯誤

    ReplyDelete
  41. 請問你填的是oauth_token_secret嗎 ?

    ReplyDelete
  42. 我試過oauth_token_secret;
    Consumer Secret;
    oauth_token_secret+Consumer Secret;
    Consumer Secret+oauth_token_secret;
    %26及不加或用&分隔
    都不行說@@

    ReplyDelete
  43. 我的傳過去

    是找不到檔案@@

    ReplyDelete
  44. 我在STEP 2 Get a Request Token 就卡住了。有試過直接將url資料改成正確丟給yahoo和寫一個form丟過去,但一直說找不到https://api.login.yahoo.com/oauth/v2/get_request_token?這個網頁呢?請問原因出在哪裡呢?

    ReplyDelete
  45. 有試過用wget看原因嗎 ?

    ReplyDelete
  46. 卡了一個問題 ....

    在步驟二 要去取get_request_token

    一直回應oauth_problem=consumer_key_rejected

    但是確認過了我的 key 是 myObject Consumer Key

    不知道該如何解決中

    ps: App Domain 也已經都確認無誤了

    ReplyDelete
  47. http://www.flickr.com/photos/doomdied/6281819797/
    確認一下你的Consumer Key是填對的,如果還是不行,也許是Project的形式錯誤,換個選項試試,我文中有提到。

    ReplyDelete
  48. 我了解大大說的Consumer key 所放的位置,我確認過了

    另外Project 在大大的文章中提到的形式,現在的連結過去已經沒有此形式可點選

    ReplyDelete
  49. 現在有分兩種,YAP跟Standard,我看了一下應該是要選YAP

    ReplyDelete
  50. 是的~我是選YAP.... 大大有SKYPE嗎???

    或是其他即時通訊呢??~~~

    ReplyDelete
  51. 詢問一下~
    dj0yJmk9YTNmSHJiNnh6aEpWJmQ9WVdrOVUyRlFRM0JzTm1zbWNHbzlNVEUxTnpBeE1EYzJNZy0tJnM9Y29uc3VtZXJzZWNyZXQmeD1hMA--

    最後兩個 '--' 也是key產生出來的???

    ReplyDelete
  52. 怪怪的問題,重新在申請後就可以了~謝謝大大的指導

    ReplyDelete
  53. 大大再提個問題~在第三階段導入yahoo的登入頁的時候,怎麼都會是英文的呢???這是跟什麼有關係?

    ps 有在第二階段 'xoauth_lang_pref' => 'zh-Hant-TW'
    帶入了

    ReplyDelete
  54. Q1 : -- 也是他給的key
    Q2 : 可能語言選項有改變過,這個要查資料或試試看才知道。

    ReplyDelete
  55. 請問我要如何取得登入後的user email?

    ReplyDelete
  56. 可以參考 Yahoo! Social SDK
    http://developer.yahoo.com/social/sdk/php/

    ReplyDelete
  57. 可以請問一下~我會一直出現"Yahoo! 無法處理你的要求。建議你與該應用程式或網站的所有者聯絡,以解決這一問題。 [95025] "
    是因為我domain是localhost造成的嗎?

    ReplyDelete
  58. 應該就是,因為他沒辦法傳值給你。

    ReplyDelete
  59. 請問在開啟YAP之後的object

    是否可以設定 應用程式的名稱呢??

    我的 開啟後都預設UntitledApp3 卻又苦苦無法修改

    不知道大大是否有逾過此問題?

    ReplyDelete
  60. 今天YAHOO的API好像卡住了,原本申請的Projects無法修改也無法新增,不知道大家會不會!?
    本來可以登入的API,突然取不到TOKEN,大家呢?

    ReplyDelete
  61. me ,too
    不過晚上登入就恢復正常了
    倒是key和權限還無法更改

    ReplyDelete
  62. 恭喜....
    我沒測試機玩之後就沒得測了

    ReplyDelete
  63. 這篇寫得很不錯
    已經找了兩個禮拜左右的plurk oauth 目前仍然無解...
    不曉得大大有沒有推薦的一些資源可以讓我學習
    謝謝~

    ReplyDelete
  64. plurk有oauth可以玩了 ?
    我還沒試過,有空玩了再來分享

    ReplyDelete
    Replies
    1. 有的..目前卡在最後一關關
      access token 老是

      Unauthorized

      40104:incorrect signature

      直接用library裡面的..不知道為什麼時間戳記會不對~"~
      所以想說先問大大有沒有什麼可以學習的資源.. :)

      Delete
  65. 他是說Signature錯誤,你的格式是HMAC-SHA1嗎 ?
    然後內容的組合是對的嗎 ?

    ReplyDelete
  66. 看樣子查錯代碼表了...
    對 我是用HMAC-SHA1
    http://code.google.com/p/oauth-php/issues/detail?id=57
    是跟著這個人的步驟做 他就是卡在access token 我想嘗試解決 但是一直失敗

    ReplyDelete
  67. 現在的App Permissions又大風吹了,很多東西找不到,請問若我只需要讀取這幾種資料的話,改勾選哪幾種的哪些動作呢?
    guid, name(familyName+givenName), email

    ReplyDelete
  68. 我好久沒玩yahoo的oauth了,找時間試了再跟你說。

    ReplyDelete
  69. 获得xoauth_yahoo_guid,怎么获取user的信息啦?

    ReplyDelete
  70. 如果是個人資料的話可以參考這個
    http://developer.yahoo.com/social/contacts/

    ReplyDelete
  71. 我step2後出現這個錯誤訊息
    OAuth Error
    Custom port is not allowed or the host is not registered with this consumer key.

    這該如何解決呢><

    ReplyDelete
  72. 我猜有可能是你的consumer key有錯

    ReplyDelete
  73. This comment has been removed by the author.

    ReplyDelete