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将向Java靠拢
Oct 09 PHP
很好用的PHP数据库类
May 27 PHP
PHP中Date()时间日期函数的使用方法小结
Apr 20 PHP
rephactor 优秀的PHP的重构工具
Jun 09 PHP
php ctype函数中文翻译和示例
Mar 21 PHP
解决CodeIgniter伪静态失效
Jun 09 PHP
php正则表达式验证(邮件地址、Url地址、电话号码、邮政编码)
Mar 14 PHP
php实现基于PDO的预处理示例
Mar 28 PHP
THINKPHP3.2使用soap连接webservice的解决方法
Dec 13 PHP
PHP基于GD2函数库实现验证码功能示例
Jan 27 PHP
PHP实现的AES 128位加密算法示例
Sep 16 PHP
在 Laravel 6 中缓存数据库查询结果的方法
Dec 11 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
php表单文件iframe异步上传实例讲解
2017/07/26 PHP
Laravel使用scout集成elasticsearch做全文搜索的实现方法
2018/11/30 PHP
laravel框架模型、视图与控制器简单操作示例
2019/10/10 PHP
JS控件autocomplete 0.11演示及下载 1月5日已更新
2007/01/09 Javascript
利用jQuery插件扩展识别浏览器内核与外壳的类型和版本的实现代码
2011/10/22 Javascript
jQuery学习笔记 操作jQuery对象 文档处理
2012/09/19 Javascript
下拉列表选择项的选中在不同浏览器中的兼容性问题探讨
2013/09/18 Javascript
javascript内存管理详细解析
2013/11/11 Javascript
JS实现带缓冲效果打开、关闭、移动一个层的方法
2015/05/09 Javascript
JS实现合并两个数组并去除重复项只留一个的方法
2015/12/17 Javascript
Js获取图片原始宽高的实现代码
2016/05/17 Javascript
深入理解JavaScript函数参数(推荐)
2016/07/26 Javascript
JS简单实现禁止访问某个页面的方法
2016/09/13 Javascript
fullCalendar中文API官方文档
2017/02/07 Javascript
js 单引号替换成双引号,双引号替换成单引号的实现方法
2017/02/16 Javascript
Node.js 8 中的重要新特性
2017/06/28 Javascript
vue 2.0 购物车小球抛物线的示例代码
2018/02/01 Javascript
微信小程序云开发实现数据添加、查询和分页
2019/05/17 Javascript
JavaScript自定义超时API代码实例
2020/04/30 Javascript
解决vuex刷新数据消失问题
2020/11/12 Javascript
对Python中Iterator和Iterable的区别详解
2018/10/18 Python
基于Python实现定时自动给微信好友发送天气预报
2018/10/25 Python
CentOS 7下安装Python3.6 及遇到的问题小结
2018/11/08 Python
python使用minimax算法实现五子棋
2019/07/29 Python
Pycharm中安装wordcloud等库失败问题及终端通过pip安装的Python库如何添加到Pycharm解释器中(推荐)
2020/05/10 Python
python使用matplotlib绘制折线图的示例代码
2020/09/22 Python
一款利用纯css3实现的超炫3D表单的实例教程
2014/12/01 HTML / CSS
只要五步 就可以用HTML5/CSS3快速制作便签贴特效(图)
2012/06/04 HTML / CSS
应用化学专业本科生求职信
2013/09/29 职场文书
初中生个人学习的自我评价
2013/12/04 职场文书
便利店的创业计划书
2014/01/15 职场文书
给同学的道歉信
2014/01/16 职场文书
小学生学习雷锋倡议书
2014/05/15 职场文书
华山导游词
2015/02/03 职场文书
创业计划书之青年旅馆
2019/09/23 职场文书
如何使用SQL Server语句创建表
2022/04/12 SQL Server