此文分為兩個單元
1 使用Yahoo OAuth2 1/2
2 使用Yahoo OAuth2 2/2
前文已申請完yahoo的api後,接下來實作的部分,原先我參考了Jex’s note 不寫下來絕對會忘…的內容,原先我也如他的原先以為只要照著做,就能順利的運作,所以我就照著他的範例來做,但是怎麼試都會出現ERROR:
$session = YahooSession::requireSession(OAUTH::CONSUMER_KEY, OAUTH::CONSUMER_SECRET, OAUTH::APP_ID);
這裡面的YahooSession到底是什麼東西啊,為什麼突然出現?後來發現它引入https://github.com/yahoo/yos-social-php/blob/master/lib/OAuth.php這個library,它的年代已經過去,同時它的方法是用YQL的方式取回資料,所以我就和Jex說的一樣:我只好參考網路的資源重刻了一個輪子:
使用OAuth2的方法來作認證
雖然Jex無法解決我的問題,但摸索中也了解了oauth2的運作,這比直接得到一個輪子有意思。以下和Jex一樣,使用CI3作為範例:
四、建立一個library
這個library 來自於[3] 由saurabhsahni寫的library,/application/libraries/Yahoooauth2.php
<?php /* Example class to access Yahoo OAuth2 protected APIs, based on https://developer.yahoo.com/oauth2/guide/ Find documentation and support on Yahoo Developer Network: https://developer.yahoo.com/forums */ class YahooOAuth2 { const AUTHORIZATION_ENDPOINT = 'https://api.login.yahoo.com/oauth2/request_auth'; const TOKEN_ENDPOINT = 'https://api.login.yahoo.com/oauth2/get_token'; public function fetch($url,$postdata="",$auth="",$headers="") { $curl = curl_init($url); if($postdata) { curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($postdata)); } else { curl_setopt($curl, CURLOPT_POST, false); } if($auth){ curl_setopt($curl, CURLOPT_USERPWD, $auth); } if($headers){ curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); } curl_setopt($curl, CURLOPT_HEADER, false); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); $response = curl_exec( $curl ); if (empty($response)) { // some kind of an error happened die(curl_error($curl)); curl_close($curl); // close cURL handler } else { $info = curl_getinfo($curl); curl_close($curl); // close cURL handler if($info['http_code'] != 200 && $info['http_code'] != 201 ) { echo "Received error: " . $info['http_code']. "\n"; echo "Raw response:".$response."\n"; die(); } } return $response; } public function getAuthorizationURL($client_id,$redirect_uri,$language="en-us") { $url = self::AUTHORIZATION_ENDPOINT; $authorization_url=$url.'?'.'client_id='.$client_id.'&redirect_uri='.$redirect_uri. '&language='.$language.'&response_type=code'; return $authorization_url; } public function get_access_token($clientId, $clientSecret,$redirect_uri,$code) { $url=self::TOKEN_ENDPOINT; $postdata=array("redirect_uri"=>$redirect_uri,"code"=>$code,"grant_type"=>"authorization_code"); $auth=$clientId . ":" . $clientSecret; $response=self::fetch($url,$postdata,$auth); // Convert the result from JSON format to a PHP array $jsonResponse = json_decode( $response ); return $jsonResponse->access_token; } } ?>
五、controller的部分,放在你的 controller function中
$this->load->library('Yahoooauth2'); define("CONSUMER_KEY", $this->config->item("yahoo_consumer_key")); define("CONSUMER_SECRET",$this->config->item("yahoo_consumer_secret")); $redirect_uri="http://".$_SERVER['SERVER_NAME'] . "/auth/login?step=8"; //設定你的回呼路徑 $social_endpoint = "https://social.yahooapis.com/v1/user/me/profile?format=json"; if (isset($_GET['code'])){ $code=$_GET['code']; } else { $code=0; } if($code){ try{ #oAuth 3-legged authorization is successful, fetch access token $token=$this->yahoooauth2->get_access_token(CONSUMER_KEY,CONSUMER_SECRET,$redirect_uri,$code); #access token is available. Do API calls. $headers= array( 'Authorization: Bearer '.$token, 'Accept: application/json', 'Content-Type: application/json' ); //Fetch Advertiser Name and Advertiser ID $resp=$this->yahoooauth2->fetch($social_endpoint,$postdata="",$auth="",$headers); $jsonResponse = json_decode( $resp); $email = $jsonResponse->profile->emails[0]->handle; $name = $jsonResponse->profile->familyName . $jsonResponse->profile->givenName; $gender = ($jsonResponse->profile->gender=="M")? 1:0; $thumb = $jsonResponse->profile->image->imageUrl; $guid = $jsonResponse->profile->guid; }catch(Exception $e){ $msg= "Yahoo認證失敗:".$e->getMessage(); }finally{ print $msg; } } else { /* no valid access token available, go to authorization server */ header("HTTP/1.1 302 Found"); header("Location: " . $this->yahoooauth2->getAuthorizationURL(CONSUMER_KEY,$redirect_uri)); exit; }
簡略說明:
2,3 行我把key/secret的值放在config中
4 設定你的回呼路徑
6-11,36-41 如果yahoo沒有回傳code,則導到yahoo進行授權確認
24 取得回呼的資料,是一個物件
25-29 回呼內容,可參考下面的物件內容:
六、取得的物件資料
stdClass Object
(
[profile] => stdClass Object
(
[guid] => FRxxxxxxxxxxxxUU4
[addresses] => Array
(
[0] => stdClass Object
(
[city] =>
[country] => TW
[current] => 1
[id] => 1
[postalCode] =>
[state] =>
[street] =>
[type] => HOME
)
[1] => stdClass Object
(
[city] =>
[country] => TW
[current] => 1
[id] => 2
[postalCode] =>
[state] =>
[street] =>
[type] => WORK
)
)
[ageCategory] => A
[created] => 2016-04-03T19:07:37Z
[emails] => Array
(
[0] => stdClass Object
(
[handle] => yourname@yahoo.com.tw
[id] => 1
[primary] => 1
[type] => HOME
)
)
[familyName] => 張
[gender] => M
[givenName] => .00
[image] => stdClass Object
(
[height] => 192
[imageUrl] => https://s.yimg.com/dh/ap/social/profile/profile_b192.png
[size] => 192x192
[width] => 192
)
[intl] => tw
[jurisdiction] => tw
[lang] => zh-Hant-TW
[memberSince] => 2016-04-02T23:14:00Z
[migrationSource] => 1
[nickname] => .河馬
[notStored] => 1
[nux] => 0
[phones] => Array
(
[0] => stdClass Object
(
[id] => 10
[number] => 886-9xxxxxx1
[type] => MOBILE
)
)
[profileMode] => PUBLIC
[profileStatus] => ACTIVE
[profileUrl] => http://profile.yahoo.com/FRxxxxxxxxxU4
[timeZone] => Asia/Shanghai
[isConnected] => 1
[profileHidden] =>
[bdRestricted] => 1
[profilePermission] => PRIVATE
[uri] => https://social.yahooapis.com/v1/user/FRxxxxxxxxxxU4/profile
)
)
能夠取得這麼完整的資料,相信你一定會很高興,祝你們使用愉快
參考資料
[3] https://github.com/saurabhsahni/php-yahoo-oauth2
原文 2016-04-05 00:04:26