6把刀 2016-09-25 23:38:47 10660次浏览 5条评论 16 3 0

https://github.com/yiisoft/yii2-authclient/blob/master/docs/guide/installation.md
这里要先配置组件。大概看官方文档,我下面写一些核心的东西

namespace frontend\components;

use Yii;
use yii\authclient\OAuth2;
use yii\web\HttpException;
use yii\authclient\OAuthToken;

class WeixinAuth extends OAuth2
{

    public $authUrl = 'https://open.weixin.qq.com/connect/oauth2/authorize';
    public $tokenUrl = 'https://api.weixin.qq.com/sns/oauth2/access_token';
    public $refreshUrl = 'https://api.weixin.qq.com/sns/oauth2/refresh_token';
    public $apiBaseUrl = 'https://api.weixin.qq.com';
    
    //构建初始访问威信URL准备去拿code
    public function buildAuthUrl(array $params = [])
    {
        $defaultParams = [
            'appid' => $this->clientId,
            'redirect_uri' => $this->getReturnUrl(),
            'response_type' => 'code',
            'scope' => 'snsapi_userinfo',
        ];

        if ($this->validateAuthState) {
            $authState = $this->generateAuthState();
            $this->setState('authState', $authState);
            $defaultParams['state'] = $authState;
        }
        $url = $this->composeUrl($this->authUrl, array_merge($defaultParams, $params));
        return $url . '#wechat_redirect';
    }

    //拿到code后也就是$authCode去拿accessToken;拿到后传给AuthHandler,并再拿到一个authclient对象。
    public function fetchAccessToken($authCode, array $params = [])
    {
        if ($this->validateAuthState) {
            $authState = $this->getState('authState');
            if (!isset($_REQUEST['state']) || empty($authState) || strcmp($_REQUEST['state'], $authState) !== 0) {
                throw new HttpException(400, 'Invalid auth state parameter.');
            } else {
                $this->removeState('authState');
            }
        }
        $defaultParams = [
            'appid' => $this->clientId,
            'secret' => $this->clientSecret,
            'code' => $authCode,
            'grant_type' => 'authorization_code',
            'redirect_uri' => $this->getReturnUrl(),
        ];
        $request = $this->createRequest()
            ->setMethod('GET')
            ->setUrl($this->tokenUrl)
            ->setData(array_merge($defaultParams, $params));
        $response = $this->sendRequest($request);
        $token = $this->createToken(['params' => $response]);
        $this->setAccessToken($token);
        return $token;
    }


    public function refreshAccessToken(OAuthToken $token)
    {//刷新accesstoken这一步我还没有测试。
        $params = [
            'appid' => $this->clientId,
            'grant_type' => 'refresh_token',
            'refresh_token' => $this->clientSecret,
        ];
        $params = array_merge($token->getParams(), $params);
        $request = $this->createRequest()
            ->setMethod('POST')
            ->setUrl($this->refreshUrl)
            ->setData($params);
        $response = $this->sendRequest($request);
        $token = $this->createToken(['params' => $response]);
        $this->setAccessToken($token);
        return $token;
    }




    protected function initUserAttributes()
    { //这一步是拿认证后的用户 详细信息,供AuthHandler处理,比如绑定会员、添加新会员等。逻辑自行处理
        $oauthToken = $this->getAccessToken();
        $defaultParams = [
            'access_token' => $oauthToken->params['access_token'],
            'openid' => $oauthToken->params['openid'],
            'lang' => 'zh-CN'
        ];
        $request = $this->createRequest()
            ->setMethod('GET')
            ->setUrl('sns/userinfo')
            ->setData($defaultParams);
        return $this->sendRequest($request);
    }

    protected function defaultName()
    {
        return 'weixin';
    }

    protected function defaultTitle()
    {
        return 'weixin';
    }


}


<?php
namespace frontend\components;

use app\models\Auth;
use app\models\User;
use Yii;
use yii\authclient\ClientInterface;
use yii\helpers\ArrayHelper;

/**
 * AuthHandler handles successful authentication via Yii auth component
 */
class AuthHandler
{
    /**
     * @var ClientInterface
     */
    private $client;

    public function __construct(ClientInterface $client)
    {
        $this->client = $client;
    }

    public function handle()
    {
        $attributes = $this->client->getUserAttributes();
        $email = ArrayHelper::getValue($attributes, 'email');
        $openid = ArrayHelper::getValue($attributes, 'openid');
        $nickname = ArrayHelper::getValue($attributes, 'login');


        /* @var Auth $auth */
        $auth = Auth::find()->where([
            'source' => $this->client->getId(),
            'source_id' => $id,
        ])->one();

        if (Yii::$app->user->isGuest) {//如果是未登录账号就处理添加账号
           
        } else { // 已登录用户就与威信号绑定

        }
    }

    /**
     * @param User $user
     */
    private function updateUserInfo(User $user)
    {
        $attributes = $this->client->getUserAttributes();
        $github = ArrayHelper::getValue($attributes, 'login');
        if ($user->github === null && $github) {
            $user->github = $github;
            $user->save();
        }
    }
}


//这里主要是拿到authtoken给authhandler后反回一个authclient的对象
use app\components\AuthHandler;

class SiteController extends Controller
{
    public function actions()
    {
        return [
            'auth' => [
                'class' => 'yii\authclient\AuthAction',
                'successCallback' => [$this, 'onAuthSuccess'],
            ],
        ];
    }

    public function onAuthSuccess($client)
    {
        (new AuthHandler($client))->handle();
    }
}
觉得很赞
  • 评论于 2016-11-24 19:22 举报

    先顶了在说,给力

  • 评论于 2017-01-11 18:29 举报

    我用了您的方法以后直接报错请在微信客户端打开链接

    3 条回复
    评论于 2017-01-12 14:22 回复

    我这个不是开发者,得在微信下面才有用的,这个是网页授权

    评论于 2017-03-13 14:08 回复

    我知道。。就是用微信自己的客户端打开的是吧。

    评论于 2017-10-05 01:59 回复

    请问Auth这个模型的表结构是怎样的能麻烦楼主发一下吗?感谢感谢

  • 评论于 2017-04-11 17:39 举报

    refreshAccessToken 方法重写时

    报这个错误:

    PHP Compile Error – yii\base\ErrorException
    
    Declaration of yii\authclient\clients\Wechat::refreshAccessToken() must be compatible with yii\authclient\BaseOAuth::refreshAccessToken(yii\authclient\OAuthToken $token)
    
  • 评论于 2017-05-17 10:27 举报

    请问:请求登录后抛出 new HttpException(400, 'Invalid auth state parameter.'); 这个异常是什么原因

    1 条回复
    评论于 2017-08-09 10:18 回复

    你的问题解决了吗? 我也遇到同样的问题了。

  • 评论于 2017-09-08 17:41 举报

    'Invalid auth state parameter. 解决办法:
    屏蔽子类这个代码即可,调用了的父类的方法里面有获取 authState

    $this->removeState('authState');
    

    或者直接使用

    https://github.com/changyuan/yii2-authclient

    即可

    1 条回复
    评论于 2018-01-07 19:01 回复

    请问 https://github.com/changyuan/yii2-authclient
    在哪设置 TOKEN 呢?

您需要登录后才可以评论。登录 | 立即注册