基于AuthClient的微信OAuth2认证写下,网上资料少,有也是比较老的,帮助下新手吧。 [ 2.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();
}
}
6把刀
注册时间:2016-02-27
最后登录:2020-11-11
在线时长:61小时30分
最后登录:2020-11-11
在线时长:61小时30分
- 粉丝8
- 金钱610
- 威望80
- 积分2020
共 5 条评论
先顶了在说,给力
我用了您的方法以后直接报错请在微信客户端打开链接
我这个不是开发者,得在微信下面才有用的,这个是网页授权
我知道。。就是用微信自己的客户端打开的是吧。
@6把刀 请问Auth这个模型的表结构是怎样的能麻烦楼主发一下吗?感谢感谢
refreshAccessToken
方法重写时报这个错误:
请问:请求登录后抛出
new HttpException(400, 'Invalid auth state parameter.');
这个异常是什么原因你的问题解决了吗? 我也遇到同样的问题了。
'Invalid auth state parameter.
解决办法:屏蔽子类这个代码即可,调用了的父类的方法里面有获取
authState
$this->removeState('authState');
或者直接使用
https://github.com/changyuan/yii2-authclient
即可
请问 https://github.com/changyuan/yii2-authclient
在哪设置 TOKEN 呢?