今天嘗試使用了微博登陸的接口,也是即將使用接入微信登陸,QQ登陸,手機號登陸、用戶名登陸等支持多種操做的問題php
微博的接口特別簡單明瞭,文檔也挺清晰的。git
採用了OAuth2.0 的方式github
請求受權 - 獲取code - 使用token獲取access_token+uid - 使用access_token+uid 獲取用戶的信息json
操做流程以下:api
1) 申請網站接入微信
http://open.weibo.com/connect - 當即建立 - 應用地址填寫你的本地測試的地址便可,其餘都是正常操做post
2) 使用文檔操做測試
http://open.weibo.com/wiki/%E... - 文檔中心網站
http://open.weibo.com/wiki/Co... - 微博登陸詳情ui
http://open.weibo.com/wiki/2/... - 獲取用戶信息接口
3) 代碼實現
我這裏沒有使用自帶的微博 phpsdk
使用了https://github.com/guzzle/guzzle 來模擬請求
爲了可擴展性接入其餘支付,我公用了一個配置文件
return [ 'log' => [ 'file' =>storage_path('logs/login/'.date('Y-m-d') . '.php') ], 'weibo' => [ // 微博登陸相關key 'w_key' => ENV('W_KEY',''), 'w_secret' => ENV('W_SECRET',''), 'w_get_code_url' => 'https://api.weibo.com/oauth2/authorize?client_id=%d&response_type=code&redirect_uri=%s', 'w_get_access_token_url' => 'https://api.weibo.com/oauth2/access_token?client_id=%d&client_secret=%s&grant_type=authorization_code&redirect_uri=%s&code=%s', 'w_user_url' => 'https://api.weibo.com/2/users/show.json' ] ];
相關配置url 採用sprintf的方式進行拼接
核心代碼以下:
控制器代碼 -
namespace App\Http\Controllers\Auth; use App\Http\Traits\LoginWeiboHandler; use Illuminate\Http\Request; class LoginWeiboController extends BaseController { use LoginWeiboHandler; /** * 微博登陸 * 調起微博登陸 - 獲取code - 攜帶code請求accessToken - 攜帶token獲取用戶信息 */ public function login(Request $request) { $code = $request->code; if (!$code) { return $this->getCode(); } $result = $this->setGetWbAccessToken($code); $access_token = $result['access_token']; $uid = $result['uid']; return $this->user($access_token,$uid); // 獲取用戶信息 } public function user($access_token,$uid) { $userInfo = $this->getUserInfo($access_token,$uid); // 執行登陸操做 $this->store($uid,'weibo',$userInfo); } }
實現類代碼 -
namespace App\Http\Traits; use GuzzleHttp\Client; use GuzzleHttp\Exception\ClientException; use App\Exceptions\LoginException; /** * 處理微博登陸邏輯 * Class LoginWeiboHandler * @package App\Http\Traits */ trait LoginWeiboHandler { private $key; private $secret; private $getCodeUrl; private $getAccessTokenUrl; private $host; private $client; public function __construct() { $this->client = new Client(); $this->key = config('login.weibo.w_key'); $this->secret = config('login.weibo.w_secret'); $this->getCodeUrl = config('login.weibo.w_get_code_url'); $this->getAccessTokenUrl = config('login.weibo.w_get_access_token_url'); $this->host = route('login.weibo'); } /** * 設置 獲取 code的url * @return string */ public function setWbCodeUrl() { $url = sprintf($this->getCodeUrl,$this->key,$this->host); return $url; } /** * @param $code string 受權後取得的code值 */ public function setGetWbAccessToken($code) { if( !$code ) { throw new LoginException([ 'message' => 'CODE不存在' ]); } $url = sprintf($this->getAccessTokenUrl,$this->key,$this->secret,$this->host,$code); try{ $res = $this->client->request('POST',$url)->getBody(); }catch (ClientException $e){ // 處理錯誤 throw new LoginException([ 'message' => 'CODE已經失效' ]); } return json_decode($res,true); } /** * 獲取code * @return \Illuminate\Http\RedirectResponse */ public function getCode() { $getCodeUrl = $this->setWbCodeUrl(); return redirect()->away($getCodeUrl); } /** * 獲取用戶信息接口 * @param $access_token * @param $uid * @return mixed * @throws LoginException * @throws \GuzzleHttp\Exception\GuzzleException */ public function getUserInfo($access_token,$uid) { $arr = [ 'access_token' => $access_token, 'uid' => $uid ]; $url = config('login.weibo.w_user_url') . '?' .http_build_query($arr); $res = $this->client->request('GET',$url); try{ $res = $this->client->request('GET',$url)->getBody(); }catch (ClientException $e){ // 處理錯誤 throw new LoginException([ 'message' => '請求微博客戶端出現問題,請選擇更換登陸方式' ]); } return json_decode($res,true); } }
4) 代碼分析
控制器代碼中,方法 getCode
用來調去微博登陸,他會進入到請求受權的界面,當你受權第一次後或者保持登陸後,會直接忽略受權頁面,直接返回code。
代碼中有個邏輯,一個是喚起登陸;一個是處理code,再次調用獲取access_token + uid
當code不存在時,代表當前須要請求受權,使用getCode方法,這個方法採用的是GET請求,會自動返回一個string信息,經過你傳遞的 redirect_uri 來決定返回到哪一個頁面(redirect_uri再個人應用-應用信息-高級信息中能夠看到) ,
因此須要使用重定向的方式來獲取數據
code存在時,使用 setGetWbAccessToken
方法獲取 access_token + uid
的值,setGetWbAccessToken 方法採用post請求,返回的是一個json參數,須要本身轉義,不會自動重定向,直接返回數據
access_token 、code 是動態的 uid是惟一的
獲取 access_token 請求用戶信息接口,getUserInfo,使用GET方法傳遞兩個值便可,若是請求報錯,容易出現錯誤,期待使用錯誤捕獲
關於用戶表的設計,以及多字段登陸的方式和方法我會再明天發出來
轉載請聯繫本人,惟一原創