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

AuthClient

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

WeChat OAuth2

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

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,须要在重载的函数里改为appidyii2

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

//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基类的中被调用,用于获取受权后的用户信息。一样的缘由,须要重载以下:yii

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接口。学习

相关文章
相关标签/搜索