关于接入微博登录的代码实现

surest · · 23 次点击 · · 开始浏览    

关于接入微博登录的代码实现

今天尝试使用了微博登录的接口,也是即将使用接入微信登录,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 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方法传递两个值即可,如果请求报错,容易出现错误,期待使用错误捕获


关于用户表的设计,以及多字段登录的方式和方法我会再明天发出来

转载请联系本人,唯一原创

来自于: http://surest.cn/article/46

本文来自:Segmentfault

感谢作者:surest

查看原文:关于接入微博登录的代码实现

23 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet