Yii2中OAuth扩展及QQ互联登录实现方法


Posted in PHP onMay 16, 2016

本文实例讲述了Yii2中OAuth扩展及QQ互联登录实现方法。分享给大家供大家参考,具体如下:

php composer.phar require --prefer-dist yiisoft/yii2-authclient "*"

Quick start 快速开始

更改Yii2的配置文件config/main.php,在components中增加如下内容

'components' => [
 'authClientCollection' => [
 'class' => 'yii\authclient\Collection',
 'clients' => [
  'google' => [
  'class' => 'yii\authclient\clients\GoogleOpenId'
  ],
  'facebook' => [
  'class' => 'yii\authclient\clients\Facebook',
  'clientId' => 'facebook_client_id',
  'clientSecret' => 'facebook_client_secret',
  ],
 ],
 ]
 ...
]

更改入口文件,一般是app/controllers/SiteController.php,在function actions增加代码,同时增加回调函数successCallback,大致如下

class SiteController extends Controller
{
 public function actions()
 {
 return [
  'auth' => [
  'class' => 'yii\authclient\AuthAction',
  'successCallback' => [$this, 'successCallback'],
  ],
 ]
 }
 public function successCallback($client)
 {
 $attributes = $client->getUserAttributes();
 // user login or signup comes here
 }
}

在登录的Views中,增加如下代码

<?= yii\authclient\widgets\AuthChoice::widget([
 'baseAuthUrl' => ['site/auth']
])?>

以上是官方的说明文档,下面我们来接入QQ互联

增加QQ登录的组件 我这里是放在 common/components/QqOAuth.php 中,源代码如下

<?php
namespace common\components;
use yii\authclient\OAuth2;
use yii\base\Exception;
use yii\helpers\Json;
/**
 *
 * ~~~
 * 'components' => [
 * 'authClientCollection' => [
 *  'class' => 'yii\authclient\Collection',
 *  'clients' => [
 *  'qq' => [
 *   'class' => 'common\components\QqOAuth',
 *   'clientId' => 'qq_client_id',
 *   'clientSecret' => 'qq_client_secret',
 *  ],
 *  ],
 * ]
 * ...
 * ]
 * ~~~
 *
 * @see http://connect.qq.com/
 *
 * @author easypao <admin@easypao.com>
 * @since 2.0
 */
class QqOAuth extends OAuth2
{
 public $authUrl = 'https://graph.qq.com/oauth2.0/authorize';
 public $tokenUrl = 'https://graph.qq.com/oauth2.0/token';
 public $apiBaseUrl = 'https://graph.qq.com';
 public function init()
 {
 parent::init();
 if ($this->scope === null) {
  $this->scope = implode(',', [
  'get_user_info',
  ]);
 }
 }
 protected function initUserAttributes()
 {
 $openid = $this->api('oauth2.0/me', 'GET');
 $qquser = $this->api("user/get_user_info", 'GET', ['oauth_consumer_key'=>$openid['client_id'], 'openid'=>$openid['openid']]);
 $qquser['openid']=$openid['openid'];
 return $qquser;
 }
 protected function defaultName()
 {
 return 'qq';
 }
 protected function defaultTitle()
 {
 return 'Qq';
 }
 /**
 * 该扩展初始的处理方法似乎QQ互联不能用,应此改写了方法
 * @see \yii\authclient\BaseOAuth::processResponse()
 */
 protected function processResponse($rawResponse, $contentType = self::CONTENT_TYPE_AUTO)
 {
   if (empty($rawResponse)) {
     return [];
   }
   switch ($contentType) {
     case self::CONTENT_TYPE_AUTO: {
       $contentType = $this->determineContentTypeByRaw($rawResponse);
       if ($contentType == self::CONTENT_TYPE_AUTO) {
   //以下代码是特别针对QQ互联登录的,也是与原方法不一样的地方 
         if(strpos($rawResponse, "callback") !== false){
           $lpos = strpos($rawResponse, "(");
           $rpos = strrpos($rawResponse, ")");
           $rawResponse = substr($rawResponse, $lpos + 1, $rpos - $lpos -1);
           $response = $this->processResponse($rawResponse, self::CONTENT_TYPE_JSON);
           break;
         }
   //代码添加结束
         throw new Exception('Unable to determine response content type automatically.');
       }
       $response = $this->processResponse($rawResponse, $contentType);
       break;
     }
     case self::CONTENT_TYPE_JSON: {
       $response = Json::decode($rawResponse, true);
       if (isset($response['error'])) {
         throw new Exception('Response error: ' . $response['error']);
       }
       break;
     }
     case self::CONTENT_TYPE_URLENCODED: {
       $response = [];
       parse_str($rawResponse, $response);
       break;
     }
     case self::CONTENT_TYPE_XML: {
       $response = $this->convertXmlToArray($rawResponse);
       break;
     }
     default: {
       throw new Exception('Unknown response type "' . $contentType . '".');
     }
   }
   return $response;
 }
}

更改 config/main.php 文件,在components中增加,大致如下

'components' => [
 'authClientCollection' => [
   'class' => 'yii\authclient\Collection',
   'clients' => [
     'qq' => [
      'class'=>'common\components\QqOAuth',
      'clientId'=>'your_qq_clientid',
      'clientSecret'=>'your_qq_secret'
    ],
   ],
 ]
]

SiteController.php 就按官方那样子

public function successCallback($client)
{
 $attributes = $client->getUserAttributes();
 // 用户的信息在$attributes中,以下是您根据您的实际情况增加的代码
 // 如果您同时有QQ互联登录,新浪微博等,可以通过 $client->id 来区别。
}

最后在登录的视图文件中 增加QQ登录链接

<a href="/site/auth?authclient=qq">使用QQ快速登录</a>
PHP 相关文章推荐
用PHP动态创建Flash动画
Oct 09 PHP
推荐Discuz!5的PHP代码高亮显示与实现可运行代码
Mar 15 PHP
php下实现伪 url 的超简单方法[转]
Sep 24 PHP
PHP 数组遍历方法大全(foreach,list,each)
Jun 30 PHP
php中截取中文字符串的代码小结
Jul 17 PHP
php shell超强免杀、减少体积工具实现代码
Oct 16 PHP
基于PHP静态类的原罪详解
May 06 PHP
计算php页面运行时间的函数介绍
Jul 01 PHP
分享下页面关键字抓取components.arrow.com站点代码
Jan 30 PHP
PHP实现支付宝即时到账功能
Dec 21 PHP
PHP实现微信小程序人脸识别刷脸登录功能
May 24 PHP
thinkphp5实现微信扫码支付
Dec 23 PHP
Yii2 assets清除缓存的方法
May 16 #PHP
php使用curl通过代理获取数据的实现方法
May 16 #PHP
php实现转换html格式为文本格式的方法
May 16 #PHP
php中array_unshift()修改数组key注意事项分析
May 16 #PHP
thinkPHP3.2简单实现文件上传的方法
May 16 #PHP
thinkPHP简单遍历数组方法分析
May 16 #PHP
thinkPHP删除前弹出确认框的简单实现方法
May 16 #PHP
You might like
从Web查询数据库之PHP与MySQL篇
2009/09/25 PHP
PHP读取ACCESS数据到MYSQL的代码
2011/05/11 PHP
php对称加密算法示例
2014/05/07 PHP
php中Array2xml类实现数组转化成XML实例
2014/12/08 PHP
php mysql_list_dbs()函数用法示例
2017/03/29 PHP
浅谈php(codeigniter)安全性注意事项
2017/04/06 PHP
PHP实现通过二维数组键值获取一维键名操作示例
2019/10/11 PHP
jQuery 绑定事件到动态创建的元素上的方法实例
2013/08/18 Javascript
Extjs grid添加一个图片状态或者按钮的方法
2014/04/03 Javascript
html的DOM中document对象forms集合用法实例
2015/01/21 Javascript
浅谈javascript中的DOM方法
2015/07/16 Javascript
jQuery在线选座位插件seat-charts特效代码分享
2015/08/27 Javascript
浅析Bootstrap验证控件的使用
2016/06/23 Javascript
JS新包管理工具yarn和npm的对比与使用入门
2016/12/09 Javascript
ES6正则的扩展实例详解
2017/04/25 Javascript
Vue.js实现输入框绑定的实例代码
2017/08/24 Javascript
JavaScript实现换肤功能
2017/09/15 Javascript
vue-cli webpack 引入jquery的方法
2018/01/10 jQuery
AngularJS对动态增加的DOM实现ng-keyup事件示例
2018/03/12 Javascript
Angular事件之不同组件间传递数据的方法
2018/11/15 Javascript
一些你可能不熟悉的JS知识点总结
2019/03/15 Javascript
浅谈vue websocket nodeJS 进行实时通信踩到的坑
2020/09/22 NodeJs
python 查找文件夹下所有文件 实现代码
2009/07/01 Python
python爬虫获取新浪新闻教学
2018/12/23 Python
简单了解python协程的相关知识
2019/08/31 Python
详解有关PyCharm安装库失败的问题的解决方法
2020/02/02 Python
HTML4和HTML5之间除了相似以外的10个主要不同
2012/12/13 HTML / CSS
使用html5制作loading图的示例
2014/04/14 HTML / CSS
德国内衣、泳装和睡衣网上商店:Bigsize Dessous
2018/07/09 全球购物
娱乐地球:Entertainment Earth
2020/01/08 全球购物
自荐信怎么写好
2013/11/11 职场文书
五星级酒店餐饮部总监的标准岗位职责
2014/02/17 职场文书
春节晚会主持词
2014/03/24 职场文书
机关作风整顿个人整改措施2014
2014/09/17 职场文书
海南召开党的群众路线教育实践活动总结大会新闻稿
2014/10/21 职场文书
2015年南京大屠杀纪念日活动总结
2015/03/24 职场文书