第一种使用EasyWeChat拉起登录
使用 composer 安装 EasyWeChat
$ composer require overtrue/wechat:~5.0 -vvv
或者在composer.json文件renquire里面添加
"overtrue/wechat": "4.2.11",
接着 composer update 就可以了
use EasyWeChat\Factory;
class Login extends Api
{
protected $app;
protected $oauth;
protected $config;
protected $noNeedLogin = ['getCode', 'loginRes'];
protected $noNeedRight = ['*'];
// 基本配置
public function _initialize()
{
parent::_initialize();
// 这里的配置信息可以写入基本配置里面,这里只是为了练手
$this->config = [
'app_id' => "wx04ff******edd2a1",
'secret' => "581671ce************5c4f634b321e",
// 下面为可选项
// 指定 API 调用返回结果的类型:array(default)/collection/object/raw/自定义类名
'response_type' => 'array',
'log' => [
'level' => 'debug',
'file' => ROOT_PATH . '/public/logs/wxOfficialAccountsLogin.log'
],
'oauth' => [
'scopes' => ['snsapi_userinfo'],
'callback' => $this->request->domain() . '/api/Login/loginRes'
],
];
$this->app = Factory::officialAccount($this->config);
$this->oauth = $this->app->oauth;
}
/**
* 网页授权获取code
*/
public function getCode(){
// TODO 前期测试用于清空值 session('wechat_user',NULL);
if (!session('wechat_user')) {
return $this->oauth->redirect()->send();
}else {
$this->success('授权登录成功(缓存)', session('wechat_user'));
}
}
/**
* 授权登录
*/
public function loginRes()
{
$code = $this->request->param('code');
if(!$code){
$this->error(__('缺少参数code!'));
}
$wechat_user = $this->oauth->user();
$result = json_decode(json_encode($wechat_user),true);
/* $result 输出结果
* Array (
[id] => oaWII632e55s0ZuqCRQHsYQkMgFE
[name] => 霍文霆
[nickname] => 霍文霆
[avatar] => https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTJn6TuXOPKCAsrDl8SfriaZcaetY04blVTKVE0deman5ApWIOe6uPOXfK8Rq5MhEETaS1ulIE4whXQ/132
[email] =>
[original] => Array (
[openid] => oaWII632e55s0ZuqCRQHsYQkMgFE
[nickname] => 霍文霆
[sex] => 1
[language] => zh_CN
[city] =>
[province] => 安徽
[country] => 中国
[headimgurl] => https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTJn6TuXOPKCAsrDl8SfriaZcaetY04blVTKVE0deman5ApWIOe6uPOXfK8Rq5MhEETaS1ulIE4whXQ/132
[privilege] => Array ( )
)
[token] => 44_XMZF2a0HHwE7Z268c_Qoi44a75hIvvw9lQi6I072ws2lop22xcYXMHoKWoA_NOo0hFH18aeXDrLejOBPf75A0Q
[access_token] => 44_XMZF2a0HHwE7Z268c_Qoi44a75hIvvw9lQi6I072ws2lop22xcYXMHoKWoA_NOo0hFH18aeXDrLejOBPf75A0Q
[refresh_token] => 44_SAM1LhD3MrQZ-xYc6uDP6fvglzDhl82wI_k2GM8wbUlG-6AcR22pXflwMTIg5fTwmYYFRYZuGhzD3ZuHE894VA
[provider] => WeChat
)*/
// 分参
extract($result);
if (!empty($result)) {
$user = User::get(['openid' => $original['openid']]);
if ($user) {
if ($user->status != 'normal') {
$this->error(__('Account is locked'));
}
// 每次调用都会更新一次用户基本数据---例如用户修改头像和昵称,这样就会实时更新数据了
$user->nickname = base64_decode(base64_encode($original['nickname']));
$user->avatar = $original['headimgurl'];
$user->save();
// 直接登陆
$ret = $this->auth->direct($user->id);
} else {
$ret = $this->auth->wxOfficialAccountsLogin($original);
}
if ($ret) {
$wechat_user = $this->auth->getUserInfo();
// 把用户登录信息写入session中,这样就不需要每次都发起请求了
session('wechat_user', $wechat_user);
$this->success('授权登录成功', $wechat_user);
} else {
$this->error('授权登录失败了!');
}
}else{
$this->error(__('授权登录失败了!'));
}
}
/* loginRes() 输出结果
* {
"code":1,
"msg":"授权登录成功",
"time":"1620469689",
"data":{
"id":3,
"nickname":"霍文霆",
"avatar":"https:\/\/thirdwx.qlogo.cn\/mmopen\/vi_32\/Q0j4TwGTfTJn6TuXOPKCAsrDl8SfriaZcaetY04blVTKVE0deman5ApWIOe6uPOXfK8Rq5MhEETaS1ulIE4whXQ\/132",
"mobile":"",
"score":0,
"token":"f3f0ce45-8dd5-4935-b292-8c5e4c66124f",
"user_id":3,
"createtime":1620469690,
"expiretime":1623061690,
"expires_in":2592000
}
}*/
// TODO 不难看出此时 loginRes() 和 session('wechat_user') 的输出结果是一样的,我也就达到目的了
/* session('wechat_user') 输出结果
* {
"code":1,
"msg":"授权登录成功(缓存)",
"time":"1620469875",
"data":{
"id":3,
"nickname":"霍文霆",
"avatar":"https:\/\/thirdwx.qlogo.cn\/mmopen\/vi_32\/Q0j4TwGTfTJn6TuXOPKCAsrDl8SfriaZcaetY04blVTKVE0deman5ApWIOe6uPOXfK8Rq5MhEETaS1ulIE4whXQ\/132",
"mobile":"",
"score":0,
"token":"f3f0ce45-8dd5-4935-b292-8c5e4c66124f",
"user_id":3,
"createtime":1620469690,
"expiretime":1623061690,
"expires_in":2592000
}
}*/
}
第二种使用原生写法拉起登录
class Login extends Api
{
protected $appid;
protected $appSecret;
protected $getCodeUrl;
protected $getTokenUrl;
protected $getUserUrl;
protected $redirectUrl;
protected $noNeedLogin = ['getCode','loginRes'];
protected $noNeedRight = ['*'];
// 基本配置
public function _initialize()
{
parent::_initialize();
$this->appid = "wx04ff******edd2a1";
$this->appSecret = "581671ce0b**********5c4f634b321e";
$this->getCodeUrl = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect';
$this->getTokenUrl = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code';
$this->getUserUrl = 'https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN';
$this->redirectUrl = urlencode($this->request->domain() . '/api/Login/loginRes');
}
/**
* 网页授权获取code
*/
public function getCode(){
// TODO 前期测试用于清空值 session('wechat_user',NULL);
if (!session('wechat_user')) {
$url = sprintf($this->getCodeUrl, $this->appid, $this->redirectUrl);
header("Location:" . $url);
}else {
$this->success('授权登录成功', session('wechat_user'));
}
}
/**
* 授权登录
*/
public function loginRes()
{
$code = $this->request->get('code'); // 获取code
if(!$code){
$this->error(__('缺少参数code!'));
}
$getTokenUrl = sprintf($this->getTokenUrl, $this->appid, $this->appSecret, $code);
// 获取access_token和openid
$result = json_decode(file_get_contents($getTokenUrl),true);
/* $result 输出结果
* Array (
[access_token] => 44_ixUtEZiza2rDbtiP2JGJKwPdNi_VA6iODMCvvRIJ-k34TbU5XR04d74ekw37QfFthPzAS2bnPaycazBXl8AInQ
[expires_in] => 7200
[refresh_token] => 44_LGyUp6YLNAdL2F8CppUXbjsxhnQpk1yvkAKZNnqSzDLN2itrfvPUY3mwFCsHHBbPF28GYyl1tMSxOuoj9sdQJg
[openid] => oaWII632e55s0ZuqCRQHsYQkMgFE
[scope] => snsapi_userinfo
)*/
if(!$result){
$this->error('获取access_token和openid失败了');
}
// 分参
extract($result);
$getUserUrl = sprintf($this->getUserUrl, $access_token, $openid);
// 获取用户信息
$userInfo = json_decode(file_get_contents($getUserUrl),true);
/* $userInfo 输出结果
* Array (
[openid] => oaWII632e55s0ZuqCRQHsYQkMgFE
[nickname] => 霍文霆
[sex] => 1
[language] => zh_CN
[city] =>
[province] => 安徽
[country] => 中国
[headimgurl] => https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTJn6TuXOPKCAsrDl8SfriaZcaetY04blVTKVE0deman5ApWIOe6uPOXfK8Rq5MhEETaS1ulIE4whXQ/132
[privilege] => Array ()
)*/
// 分参
extract($userInfo);
if (!empty($userInfo)) {
$user = User::get(['openid' => $openid]);
if ($user) {
if ($user->status != 'normal') {
$this->error(__('Account is locked'));
}
// 每次调用都会更新一次用户基本数据---例如用户修改头像和昵称,这样就会实时更新数据了
$user->nickname = base64_decode(base64_encode($nickname));
$user->avatar = $headimgurl;
$user->save();
// 直接登陆
$ret = $this->auth->direct($user->id);
} else {
$ret = $this->auth->wxOfficialAccountsLogin($userInfo);
}
if ($ret) {
$wechat_user = $this->auth->getUserInfo();
// 把用户登录信息写入session中,这样就不需要每次都发起请求了
session('wechat_user', $wechat_user);
$this->success('授权登录成功', $wechat_user);
} else {
$this->error('授权登录失败了!');
}
}else{
$this->error(__('获取用户信息失败了'));
}
}
/* loginRes() 输出结果
* {
"code":1,
"msg":"授权登录成功",
"time":"1620468028",
"data":{
"id":2,
"nickname":"霍文霆",
"avatar":"https:\/\/thirdwx.qlogo.cn\/mmopen\/vi_32\/Q0j4TwGTfTJn6TuXOPKCAsrDl8SfriaZcaetY04blVTKVE0deman5ApWIOe6uPOXfK8Rq5MhEETaS1ulIE4whXQ\/132",
"mobile":"",
"score":0,
"token":"d4e89893-c4fa-4d70-a373-92bd7c454250",
"user_id":2,
"createtime":1620468029,
"expiretime":1623060029,
"expires_in":2592000
}
}*/
// TODO 不难看出此时 loginRes() 和 session('wechat_user') 的输出结果是一样的,我也就达到目的了
/* session('wechat_user') 输出结果
* {
"code":1,
"msg":"授权登录成功",
"time":"1620468151",
"data":{
"id":2,
"nickname":"霍文霆",
"avatar":"https:\/\/thirdwx.qlogo.cn\/mmopen\/vi_32\/Q0j4TwGTfTJn6TuXOPKCAsrDl8SfriaZcaetY04blVTKVE0deman5ApWIOe6uPOXfK8Rq5MhEETaS1ulIE4whXQ\/132",
"mobile":"",
"score":0,
"token":"d4e89893-c4fa-4d70-a373-92bd7c454250",
"user_id":2,
"createtime":1620468029,
"expiretime":1623060029,
"expires_in":2592000
}
}*/
}
在 app\common\library 添加如下方法,我是基于fastadmin开发的,也可以改写我的数据写入方式
/**
* 微信公众号H5注册用户
* @param string $username 用户名
* @param string $password 密码
* @param string $email 邮箱
* @param string $mobile 手机号
* @param array $extend 扩展参数
* @return boolean
*/
public function wxOfficialAccountsLogin($result)
{
// 分参
extract($result);
$params = [
'openid' => $openid,
'nickname' => base64_decode(base64_encode($nickname)),
'avatar' => $headimgurl,
'jointime' => time(),
'joinip' => request()->ip(),
'logintime' => time(),
'loginip' => request()->ip(),
'prevtime' => time(),
'status' => 'normal'
];
Db::startTrans();
try {
$user = User::create($params, true);
$this->_user = User::get($user->id);
//设置Token
$this->_token = Random::uuid();
Token::set($this->_token, $user->id, $this->keeptime);
Db::commit();
} catch (Exception $e) {
$this->setError($e->getMessage());
Db::rollback();
return false;
}
return true;
}