關於接入微博登入的程式碼實現
今天嘗試使用了微博登入的介面,也是即將使用接入微信登入,QQ登入,手機號登入、使用者名稱登入等支援多種操作的問題
微博的介面特別簡單明瞭,文件也挺清晰的。
採用了OAuth2.0 的方式
請求授權 – 獲取code – 使用token獲取access_token+uid – 使用access_token+uid 獲取使用者的資訊
操作流程如下:
1) 申請網站接入
http://open.weibo.com/connect – 立即建立 – 應用地址填寫你的本地測試的地址即可,其他都是正常操作
2) 使用文件操作
http://open.weibo.com/wiki/%E… – 文件中心
http://open.weibo.com/wiki/Co… – 微博登入詳情
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 AppHttpControllersAuth;
use AppHttpTraitsLoginWeiboHandler;
use IlluminateHttpRequest;
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 AppHttpTraits;
use GuzzleHttpClient;
use GuzzleHttpExceptionClientException;
use AppExceptionsLoginException;
/**
* 處理微博登入邏輯
* Class LoginWeiboHandler
* @package AppHttpTraits
*/
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 IlluminateHttpRedirectResponse
*/
public function getCode()
{
$getCodeUrl = $this->setWbCodeUrl();
return redirect()->away($getCodeUrl);
}
/**
* 獲取使用者資訊介面
* @param $access_token
* @param $uid
* @return mixed
* @throws LoginException
* @throws GuzzleHttpExceptionGuzzleException
*/
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方法傳遞兩個值即可,如果請求報錯,容易出現錯誤,期待使用錯誤捕獲
關於使用者表的設計,以及多欄位登入的方式和方法我會再明天發出來
轉載請聯絡本人,唯一原創