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项目开发中最常用的自定义函数整理
Dec 02 PHP
jQuery 源码分析笔记
May 25 PHP
PHP FATAL ERROR: CALL TO UNDEFINED FUNCTION BCMUL()解决办法
May 04 PHP
PHP实现自动识别Restful API的返回内容类型
Feb 07 PHP
PHP调用.NET的WebService 简单实例
Mar 27 PHP
php基于Snoopy解析网页html的方法
Jul 09 PHP
php版微信公众平台实现预约提交后发送email的方法
Sep 26 PHP
PHP实现权限管理功能示例
Sep 22 PHP
OAuth认证协议中的HMACSHA1加密算法(实例)
Oct 25 PHP
php获取ajax的headers方法与内容实例
Dec 27 PHP
PHP数据对象映射模式实例分析
Mar 29 PHP
php curl操作API接口类完整示例
May 21 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
hadoop常见错误以及处理方法详解
2013/06/19 PHP
基于PHP实现假装商品限时抢购繁忙的效果
2015/10/16 PHP
PHP针对伪静态的注入总结【附asp与Python相关代码】
2017/08/01 PHP
php判断某个方法是否存在函数function_exists (),method_exists()与is_callable()区别与用法解析
2020/04/20 PHP
Thinkphp 框架扩展之行为扩展原理与实现方法分析
2020/04/23 PHP
jqPlot jquery的页面图表绘制工具
2009/07/25 Javascript
基于JQuery框架的AJAX实例代码
2009/11/03 Javascript
测试你的JS的掌握程度的代码
2009/12/09 Javascript
多种方式实现JS调用后台方法进行数据交互
2013/08/20 Javascript
利用jq让你的div居中的好方法分享
2013/11/21 Javascript
网页广告中JS代码的信息监听示例
2014/04/02 Javascript
jQuery中insertAfter()方法用法实例
2015/01/08 Javascript
javascript 中的 delete及delete运算符
2015/11/15 Javascript
javascript合并表格单元格实例代码
2016/01/03 Javascript
jQuery中JSONP的两种实现方式详解
2016/09/26 Javascript
js验证手机号、密码、短信验证码代码工具类
2020/06/24 Javascript
vue实现未登录跳转到登录页面的方法
2018/07/17 Javascript
vue踩坑记-在项目中安装依赖模块npm install报错
2019/04/02 Javascript
Vue实现数据表格合并列rowspan效果
2020/11/30 Javascript
2019最新21个MySQL高频面试题介绍
2020/02/06 Javascript
JavaScript享元模式原理与用法实例详解
2020/03/09 Javascript
解决Vue @submit 提交后不刷新页面问题
2020/07/18 Javascript
删除目录下相同文件的python代码(逐级优化)
2012/05/25 Python
python 常用的基础函数
2018/07/10 Python
Tensorflow模型实现预测或识别单张图片
2019/07/19 Python
解决pycharm启动后总是不停的updating indices...indexing的问题
2019/11/27 Python
TensorFlow打印输出tensor的值
2020/04/19 Python
CHARLES & KEITH台湾官网:新加坡时尚品牌
2019/07/30 全球购物
大学学年自我鉴定
2013/10/28 职场文书
实验室的标语
2014/06/20 职场文书
我与祖国共奋进演讲稿
2014/09/13 职场文书
群众路线教育实践活动心得体会(教师)
2014/10/31 职场文书
2015关爱留守儿童工作总结
2014/12/12 职场文书
当你找不到方向的时候,不妨读读刘备的一生
2019/08/05 职场文书
用Python编写简单的gRPC服务的详细过程
2021/07/04 Python
python index() 与 rindex() 方法的使用示例详解
2022/12/24 Python