文档章节

Yii2 Day 11 添加微信第三方登录

_Elvis
 _Elvis
发布于 2015/12/25 16:21
字数 610
阅读 1657
收藏 13

AuthClient

Yii官方写的第三方登录扩展,可以封装了基于OpenId,OAuth1,OAuth2标准的第三方授权登录过程,可以轻松实现Facebook,GitHub,Google,LinkedIn等第三方登录集成。无奈官方自带的几个第三方(Facebook,Google)等在天朝基本没有意义,基本上只有借鉴学习的作用了。不过按照AuthClient的预定义接口,可以轻松实现微信的OAuth登陆。

WeChat OAuth2

AuthClient的每个第三方登陆实现,都是通过扩展OAuth2这个类实现。先看下第一个函数:

OAuth2.php
 
/**
 * Composes user authorization URL.
 * @param array $params additional auth GET params.
 * @return string authorization URL.
*/
public function buildAuthUrl(array $params = [])
{
    $defaultParams = [
        'client_id' => $this->clientId,
        'response_type' => 'code',
        'redirect_uri' => $this->getReturnUrl(),
        'xoauth_displayname' => Yii::$app->name,
    ];
    if (!empty($this->scope)) {
        $defaultParams['scope'] = $this->scope;
    }
    return $this->composeUrl($this->authUrl, array_merge($defaultParams, $params));
}

用于构建发起OAuth授权的URL,由于微信的请求URL要求带有'#wechat_redirect',而这个函数实现没有为这个额外的字符串预留位置,因此,需要重载这个函数:

//WeChat.php

    public function buildAuthUrl(array $params = [])
    {
        $defaultParams = [
            'appid' => $this->clientId,
            'redirect_uri' => $this->getReturnUrl(),
            'response_type'=>'code',
            'scope'=>$this->scope,
            'state'=>base64_encode(\Yii::$app->user->returnUrl)
        ];

        $url = $this->composeUrl($this->authUrl, array_merge($defaultParams, $params));
        return $url . '#wechat_redirect';
    }

注意,基类用的是client_id,而微信要求的是appid,需要在重载的函数里改成appid

第二个函数是fetchAccessToken,同样的,需要重载,这里只给出重载后的代码:

//WeChat.php

    public function fetchAccessToken($authCode, array $params = [])
    {
        $defaultParams = [
            'appid' => $this->clientId,
            'secret' => $this->clientSecret,
            'code' => $authCode,
            'grant_type' => 'authorization_code',
            'redirect_uri' => $this->getReturnUrl(),
        ];
        $response = $this->sendRequest('GET', $this->tokenUrl, array_merge($defaultParams, $params));
        $token = null;
        if(isset($response['access_token']))
        {
            $arr['oauth_token_secret'] = $this->clientSecret;
            $token = $this->createToken(['params' => array_merge($arr,$response),'class'=>WeChatToken::className()]);
            $this->setAccessToken($token);
        }
        return $token;
    }

第三个需要重载的函数是apiInternal,该函数在BaseOAuth基类的中被调用,用于获取授权后的用户信息。同样的原因,需要重载如下:

 protected function apiInternal($accessToken, $url, $method, array $params, array $headers)
    {
        /** @var $accessToken WeChatToken */
        $params['access_token'] = $accessToken->getToken();
        $params['openid'] = $accessToken->getOpenID();
        $params['lang'] = 'zh_CN';
        return $this->sendRequest($method, $url, $params, $headers);
    }

自此,首次授权是没问题了,再完善下刷新token的接口吧:

public function refreshAccessToken(OAuthToken $token)
    {
        /**
         * @var $token WeChatToken
         */
        $params = [
            'appid' => $this->clientId,
            'refresh_token' => $token->getRefreshToken(),
            'grant_type' => 'refresh_token'
        ];
        $response = $this->sendRequest('GET', $this->refreshTokenUrl, $params);
        $token = null;
        if(isset($response['access_token']))
        {
            $arr['oauth_token_secret'] = $this->clientSecret;
            $token = $this->createToken(['params' => array_merge($arr,$response),'class'=>WeChatToken::className()]);
            $this->setAccessToken($token);
        }
        return $token;

    }

如果使用的是yii2-user的扩展,还有一些额外的接口需要实现,具体查看ClientInterface接口。

© 著作权归作者所有

共有 人打赏支持
_Elvis
粉丝 76
博文 41
码字总数 29082
作品 0
海淀
程序员
加载中

评论(3)

帅哥Q
帅哥Q
有没有完整的demo?
_Elvis
_Elvis

引用来自“宏哥说的都是对的”的评论

本人小菜,请问wechart.php放在那个目录比较好?
放那个模块的components目录下就行,有namespace了,放哪里都行
宏哥说的都是对的
本人小菜,请问wechart.php放在那个目录比较好?
基于 Yii2 的后台基础框架--RageFrame

RageFrame 为二次开发而生,让开发变得更简单。 前言 RageFrame项目创建于2016年4月16日,基于Yii2框架开发的应用开发引擎,正在慢慢成长中,目的是为了集成更多的基础功能,不在为相同的基础...

简言Personal
2017/08/01
795
3
记录Yii2框架开发遇到微信错误提示

转载地址 记录Yii2框架开发遇到微信错误提示 微信公共号开发,提示“该公众号暂时无法提供服务,请稍后再试”,如何解决? 以前使用Yii框架的时候,并没有像Yii2,以前的Yii框架似乎用起来在...

durban
07/22
0
0
composer yii2 mailer redis 包制作

1.github 创建项目 ,项目名称:yii2mailerqueue 2.制作并上传包 a.首先clone yii2_mailerqueue 项目 b.打开yii2mailerqueue文件,把开发测试完成的源码文件夹 src 复制黏贴到yii2mailerqueue根...

罗培海
2017/10/25
0
0
Yii2 Day 5: 创建用户模块

在确定了模块化开发应用的方向后,可以尝试写一个模块练练手啦。首先想到的就是用户模块。 前后台用户分离 通常一个应用会存在前台用户和后台用户,这两个用户的Session变量必须是分开的,不...

_Elvis
2014/12/17
0
1
技术积累笔记概要

2015年11月24日 1、rest 速率限制,写属于自己的方法。 2、actions方法深刻了解。 3、YII技术博客:http://blog.csdn.net/terrywater/article/category/2565815。 4、静态方法传递参数的习惯...

风清扬-深圳
2015/11/24
78
0

没有更多内容

加载失败,请刷新页面

加载更多

如何通过 J2Cache 实现分布式 session 存储

做 Java Web 开发的人多数都会需要使用到 session (会话),我们使用 session 来保存一些需要在两个不同的请求之间共享数据。一般 Java 的 Web 容器像 Tomcat、Resin、Jetty 等等,它们会在...

红薯
今天
1
0
C++ std::thread

C++11提供了std::thread类来表示一个多线程对象。 1,首先介绍一下std::this_thread命名空间: (1)std::this_thread::get_id():返回当前线程id (2)std::this_thread::yield():用户接口...

yepanl
今天
2
0
Nignx缓存文件与动态文件自动均衡的配置

下面这段nginx的配置脚本的作用是,自动判断是否存在缓存文件,如果有优先输出缓存文件,不经过php,如果没有,则回到php去处理,同时生成缓存文件。 PHP框架是ThinkPHP,最后一个rewrite有关...

swingcoder
今天
1
0
20180920 usermod命令与用户密码管理

命令 usermod usermod 命令的选项和 useradd 差不多。 一个用户可以属于多个组,但是gid只有一个;除了gid,其他的组(groups)叫做扩展组。 usermod -u 1010 username # 更改用户idusermod ...

野雪球
今天
1
0
Java网络编程基础

1. 简单了解网络通信协议TCP/IP网络模型相关名词 应用层(HTTP,FTP,DNS等) 传输层(TCP,UDP) 网络层(IP,ICMP等) 链路层(驱动程序,接口等) 链路层:用于定义物理传输通道,通常是对...

江左煤郎
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部