今天嘗試使用了微博登錄的接口浆竭,也是即將使用接入微信登錄胁出,QQ登錄迫悠,手機(jī)號登錄谆趾、用戶名登錄等支持多種操作的問題
微博的接口特別簡單明了携添,文檔也挺清晰的嫁盲。
采用了OAuth2.0 的方式
請求授權(quán) - 獲取code - 使用token獲取access_token+uid - 使用access_token+uid 獲取用戶的信息
操作流程如下:
-
申請網(wǎng)站接入
http://open.weibo.com/connect - 立即創(chuàng)建 - 應(yīng)用地址填寫你的本地測試的地址即可,其他都是正常操作
-
使用文檔操作
http://open.weibo.com/wiki/%E9%A6%96%E9%A1%B5 - 文檔中心
http://open.weibo.com/wiki/Connect/login - 微博登錄詳情
http://open.weibo.com/wiki/2/users/show - 獲取用戶信息接口
-
代碼實(shí)現(xiàn)
我這里沒有使用自帶的微博 phpsdk
使用了https://github.com/guzzle/guzzle 來模擬請求
為了可擴(kuò)展性接入其他支付烈掠,我公用了一個配置文件
return [ 'log' => [ 'file' =>storage_path('logs/login/'.date('Y-m-d') . '.php') ], 'weibo' => [ // 微博登錄相關(guān)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' ] ];
相關(guān)配置url 采用sprintf的方式進(jìn)行拼接
核心代碼如下:
控制器代碼 -
namespace App\Http\Controllers\Auth; use App\Http\Traits\LoginWeiboHandler; use Illuminate\Http\Request; class LoginWeiboController extends BaseController { use LoginWeiboHandler; /** * 微博登錄 * 調(diào)起微博登錄 - 獲取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); // 執(zhí)行登錄操作 $this->store($uid,'weibo',$userInfo); } }
實(shí)現(xiàn)類代碼 -
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'); } /** * 設(shè)置 獲取 code的url * @return string */ public function setWbCodeUrl() { $url = sprintf($this->getCodeUrl,$this->key,$this->host); return $url; } /** * @param $code string 授權(quán)后取得的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已經(jīng)失效' ]); } 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' => '請求微博客戶端出現(xiàn)問題羞秤,請選擇更換登錄方式' ]); } return json_decode($res,true); } }
-
代碼分析
控制器代碼中,方法
getCode
用來調(diào)去微博登錄左敌,他會進(jìn)入到請求授權(quán)的界面瘾蛋,當(dāng)你授權(quán)第一次后或者保持登錄后,會直接忽略授權(quán)頁面矫限,直接返回code哺哼。代碼中有個邏輯,一個是喚起登錄叼风;一個是處理code取董,再次調(diào)用獲取access_token + uid
當(dāng)code不存在時,表明當(dāng)前需要請求授權(quán)无宿,使用getCode方法茵汰,這個方法采用的是GET請求,會自動返回一個string信息孽鸡,通過你傳遞的 redirect_uri 來決定返回到哪個頁面(redirect_uri再我的應(yīng)用-應(yīng)用信息-高級信息中可以看到) 蹂午,
所以需要使用重定向的方式來獲取數(shù)據(jù)code存在時,使用
setGetWbAccessToken
方法獲取access_token + uid
的值彬碱,setGetWbAccessToken 方法采用post請求画侣,返回的是一個json參數(shù),需要自己轉(zhuǎn)義堡妒,不會自動重定向配乱,直接返回?cái)?shù)據(jù)access_token 、code 是動態(tài)的 uid是唯一的
獲取 access_token 請求用戶信息接口皮迟,getUserInfo搬泥,使用GET方法傳遞兩個值即可,如果請求報(bào)錯伏尼,容易出現(xiàn)錯誤忿檩,期待使用錯誤捕獲
關(guān)于用戶表的設(shè)計(jì),以及多字段登錄的方式和方法我會再明天發(fā)出來
轉(zhuǎn)載請聯(lián)系本人爆阶,唯一原創(chuàng)