今天尝试使用了微博登陆的接口,也是即将使用接入微信登陆,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方法传递两个值便可,若是请求报错,容易出现错误,期待使用错误捕获
关于用户表的设计,以及多字段登陆的方式和方法我会再明天发出来
转载请联系本人,惟一原创