2022-08-19 19:48:37 +08:00
|
|
|
<?php
|
|
|
|
|
declare (strict_types=1);
|
|
|
|
|
// +----------------------------------------------------------------------
|
|
|
|
|
// | swiftAdmin 极速开发框架 [基于WebMan开发]
|
|
|
|
|
// +----------------------------------------------------------------------
|
|
|
|
|
// | Copyright (c) 2020-2030 http://www.swiftadmin.net
|
|
|
|
|
// +----------------------------------------------------------------------
|
|
|
|
|
// | swiftAdmin.net High Speed Development Framework
|
|
|
|
|
// +----------------------------------------------------------------------
|
|
|
|
|
// | Author: meystack <coolsec@foxmail.com> Apache 2.0 License
|
|
|
|
|
// +----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
namespace app\index\controller;
|
|
|
|
|
|
|
|
|
|
use app\common\library\ResultCode;
|
2023-06-19 14:32:30 +08:00
|
|
|
use app\common\service\user\UserService;
|
|
|
|
|
use app\common\service\user\UserTokenService;
|
2022-08-19 19:48:37 +08:00
|
|
|
use app\HomeController;
|
|
|
|
|
use app\common\model\system\User;
|
|
|
|
|
use app\common\model\system\UserThird;
|
2023-06-19 14:32:30 +08:00
|
|
|
use Psr\SimpleCache\InvalidArgumentException;
|
2022-08-19 19:48:37 +08:00
|
|
|
use support\Response;
|
|
|
|
|
use system\Random;
|
2022-11-28 19:11:12 +08:00
|
|
|
use think\db\exception\DataNotFoundException;
|
|
|
|
|
use think\db\exception\DbException;
|
|
|
|
|
use think\db\exception\ModelNotFoundException;
|
2022-08-19 19:48:37 +08:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 社会化登录
|
|
|
|
|
* @ QQ 微信 微博
|
|
|
|
|
*/
|
|
|
|
|
class Third extends HomeController
|
|
|
|
|
{
|
|
|
|
|
/**
|
|
|
|
|
* 类型
|
2022-11-28 19:11:12 +08:00
|
|
|
* @var mixed
|
2022-08-19 19:48:37 +08:00
|
|
|
*/
|
2022-11-28 19:11:12 +08:00
|
|
|
public mixed $type;
|
2022-08-19 19:48:37 +08:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 类型实例
|
2022-11-28 19:11:12 +08:00
|
|
|
* @var mixed
|
2022-08-19 19:48:37 +08:00
|
|
|
*/
|
2022-11-28 19:11:12 +08:00
|
|
|
public mixed $oauth;
|
2022-08-19 19:48:37 +08:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @var array
|
|
|
|
|
*/
|
2022-11-28 19:11:12 +08:00
|
|
|
public array $repeatLogin = [];
|
2022-08-19 19:48:37 +08:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 初始化构造函数
|
|
|
|
|
*/
|
|
|
|
|
public function __construct()
|
|
|
|
|
{
|
|
|
|
|
parent::__construct();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取第三方登录配置
|
|
|
|
|
* @return mixed|string
|
|
|
|
|
* @throws \Exception
|
|
|
|
|
*/
|
|
|
|
|
private function oType()
|
|
|
|
|
{
|
|
|
|
|
$this->type = input('type');
|
|
|
|
|
$class = "\\system\\third\\" . $this->type;
|
|
|
|
|
if (!class_exists($class)) {
|
|
|
|
|
throw new \Exception('暂时还不支持该方式扩展');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new $class;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 用户登录操作
|
|
|
|
|
*/
|
2022-11-28 19:11:12 +08:00
|
|
|
public function login(): Response
|
2022-08-19 19:48:37 +08:00
|
|
|
{
|
|
|
|
|
try {
|
|
|
|
|
$this->oauth = $this->oType();
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
return $this->error($e->getMessage());
|
|
|
|
|
}
|
|
|
|
|
$referer = input('ref', request()->server('HTTP_REFERER', '/'));
|
|
|
|
|
request()->cookie('redirectUrl', $referer);
|
|
|
|
|
return $this->oauth->login();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 用户回调函数
|
2023-06-19 14:32:30 +08:00
|
|
|
* @return Response
|
2022-11-28 19:11:12 +08:00
|
|
|
* @throws DataNotFoundException
|
|
|
|
|
* @throws DbException
|
|
|
|
|
* @throws ModelNotFoundException
|
2023-06-19 14:32:30 +08:00
|
|
|
* @throws InvalidArgumentException
|
2022-08-19 19:48:37 +08:00
|
|
|
*/
|
|
|
|
|
public function callback()
|
|
|
|
|
{
|
|
|
|
|
try {
|
|
|
|
|
$this->oauth = $this->oType();
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
return $this->error($e->getMessage());
|
|
|
|
|
}
|
2022-12-02 11:16:57 +08:00
|
|
|
$user = $this->oauth->getUserInfo();
|
2023-06-19 14:32:30 +08:00
|
|
|
if (!empty($user) && !UserTokenService::isLogin()) {
|
2022-12-02 11:16:57 +08:00
|
|
|
return $this->register($user, $this->type);
|
2023-06-19 14:32:30 +08:00
|
|
|
} else if (UserTokenService::isLogin()) { // 绑定用户
|
2022-12-02 11:16:57 +08:00
|
|
|
return $this->doBind($user, $this->type);
|
2022-08-19 19:48:37 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 用户注册操作
|
2022-12-02 11:16:57 +08:00
|
|
|
* @param array $info
|
2022-08-19 19:48:37 +08:00
|
|
|
* @param string|null $type
|
2022-11-28 19:11:12 +08:00
|
|
|
* @return Response
|
|
|
|
|
* @throws DataNotFoundException
|
|
|
|
|
* @throws DbException
|
|
|
|
|
* @throws ModelNotFoundException
|
2022-08-19 19:48:37 +08:00
|
|
|
*/
|
2022-12-02 11:16:57 +08:00
|
|
|
protected function register(array $info = [], string $type = null)
|
2022-08-19 19:48:37 +08:00
|
|
|
{
|
2022-12-02 11:16:57 +08:00
|
|
|
$openid = $info['openid'] ?? $info['id'];
|
|
|
|
|
$nickname = $info['userData']['name'] ?? $info['userData']['nickname'];
|
|
|
|
|
$userInfo = UserThird::alias('th')->view('user', '*', 'user.id=th.user_id')->where(['openid' => $openid, 'type' => $type])->find();
|
|
|
|
|
|
|
|
|
|
if (!empty($userInfo)) {
|
2022-08-19 19:48:37 +08:00
|
|
|
$array['login_time'] = time();
|
2022-08-23 11:11:42 +08:00
|
|
|
$array['login_ip'] = request()->getRealIp();
|
2022-12-02 11:16:57 +08:00
|
|
|
$array['login_count'] = $userInfo['login_count'] + 1;
|
2023-06-19 14:32:30 +08:00
|
|
|
if (User::update($array, ['id' => $userInfo['user_id']])) {
|
|
|
|
|
UserService::createUserCookies($userInfo);
|
|
|
|
|
return redirect(request()->cookie('redirectUrl', '/'));
|
2022-08-19 19:48:37 +08:00
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
|
|
// 注册本地用户
|
2023-06-19 14:32:30 +08:00
|
|
|
$post['nickname'] = $nickname;
|
|
|
|
|
$post['avatar'] = $info['userData']['avatar'];
|
2022-08-19 19:48:37 +08:00
|
|
|
if (User::getByNickname($nickname)) {
|
2023-06-19 14:32:30 +08:00
|
|
|
$post['nickname'] .= Random::alpha(3);
|
2022-08-19 19:48:37 +08:00
|
|
|
}
|
2023-06-19 14:32:30 +08:00
|
|
|
$post['group_id'] = 1;
|
|
|
|
|
$post['create_ip'] = request()->getRealIp();
|
|
|
|
|
$result = UserService::register($post);
|
2022-08-19 19:48:37 +08:00
|
|
|
|
|
|
|
|
// 封装第三方数据
|
|
|
|
|
if (!empty($result)) {
|
2023-06-19 14:32:30 +08:00
|
|
|
$third = [
|
2022-08-19 19:48:37 +08:00
|
|
|
'type' => $this->type,
|
|
|
|
|
'user_id' => $result['id'],
|
|
|
|
|
'openid' => $openid,
|
|
|
|
|
'nickname' => $nickname,
|
2022-12-02 11:16:57 +08:00
|
|
|
'access_token' => $info['access_token'],
|
|
|
|
|
'refresh_token' => $info['refresh_token'],
|
|
|
|
|
'expires_in' => $info['expires_in'],
|
2022-08-19 19:48:37 +08:00
|
|
|
'login_time' => time(),
|
2022-12-02 11:16:57 +08:00
|
|
|
'expiretime' => time() + $info['expires_in'],
|
2022-08-19 19:48:37 +08:00
|
|
|
];
|
|
|
|
|
|
2023-06-19 14:32:30 +08:00
|
|
|
if (UserThird::create($third)) {
|
|
|
|
|
UserService::createUserCookies($result);
|
|
|
|
|
return redirect(request()->cookie('redirectUrl', '/'));
|
2022-08-19 19:48:37 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $this->error('登录失败');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 用户绑定操作
|
|
|
|
|
* @return Response
|
2023-06-19 14:32:30 +08:00
|
|
|
* @throws InvalidArgumentException
|
2022-08-19 19:48:37 +08:00
|
|
|
*/
|
2022-11-28 19:11:12 +08:00
|
|
|
public function bind(): Response
|
2022-08-19 19:48:37 +08:00
|
|
|
{
|
2023-06-19 14:32:30 +08:00
|
|
|
if (UserTokenService::isLogin()) {
|
2022-08-19 19:48:37 +08:00
|
|
|
$buildQuery = [
|
|
|
|
|
'bind' => true,
|
|
|
|
|
'type' => input('type'),
|
|
|
|
|
'ref' => input('ref', request()->server('HTTP_REFERER', '/')),
|
|
|
|
|
];
|
|
|
|
|
|
2023-06-19 14:32:30 +08:00
|
|
|
return $this->redirect("/third/login?" . http_build_query($buildQuery));
|
2022-08-19 19:48:37 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $this->error('请先登录');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 用户解除绑定
|
2023-06-19 14:32:30 +08:00
|
|
|
* @return Response
|
2022-11-28 19:11:12 +08:00
|
|
|
* @throws DbException
|
2023-06-19 14:32:30 +08:00
|
|
|
* @throws InvalidArgumentException
|
2022-08-19 19:48:37 +08:00
|
|
|
*/
|
2022-11-28 19:11:12 +08:00
|
|
|
public function unbind(): Response
|
2022-08-19 19:48:37 +08:00
|
|
|
{
|
|
|
|
|
try {
|
|
|
|
|
$this->oauth = $this->oType();
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
return $this->error($e->getMessage());
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-19 14:32:30 +08:00
|
|
|
$result = UserTokenService::isLogin();
|
|
|
|
|
if (!empty($result)) {
|
2022-08-19 19:48:37 +08:00
|
|
|
|
2023-06-19 14:32:30 +08:00
|
|
|
if (empty($result['email']) || empty($result['pwd'])) {
|
|
|
|
|
return $this->error('解除绑定需要设置邮箱和密码!');
|
|
|
|
|
}
|
2022-08-19 19:48:37 +08:00
|
|
|
|
2023-06-19 14:32:30 +08:00
|
|
|
$where['type'] = $this->type;
|
2023-06-23 17:46:05 +08:00
|
|
|
$where['user_id'] = request()->userId;
|
2023-06-19 14:32:30 +08:00
|
|
|
if (UserThird::where($where)->delete()) {
|
|
|
|
|
return $this->success('解除绑定成功!');
|
2022-08-19 19:48:37 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $this->error();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 用户绑定操作实例
|
2022-12-02 11:16:57 +08:00
|
|
|
* @param array $info
|
2022-08-19 19:48:37 +08:00
|
|
|
* @param string|null $type
|
2022-11-28 19:11:12 +08:00
|
|
|
* @return Response|null
|
|
|
|
|
* @throws DataNotFoundException
|
|
|
|
|
* @throws DbException
|
|
|
|
|
* @throws ModelNotFoundException
|
2022-08-19 19:48:37 +08:00
|
|
|
*/
|
2022-12-02 11:16:57 +08:00
|
|
|
protected function doBind(array $info = [], string $type = null)
|
2022-08-19 19:48:37 +08:00
|
|
|
{
|
2022-12-02 11:16:57 +08:00
|
|
|
$openid = $info['openid'] ?? $info['id'];
|
|
|
|
|
$nickname = $info['userData']['name'] ?? $info['userData']['nickname'];
|
2022-08-19 19:48:37 +08:00
|
|
|
// 查询是否被注册
|
|
|
|
|
$where['openid'] = $openid;
|
|
|
|
|
$where['type'] = $this->type;
|
|
|
|
|
if (!UserThird::where($where)->find()) {
|
|
|
|
|
|
|
|
|
|
// 拼装数据
|
|
|
|
|
$third = [
|
|
|
|
|
'type' => $type,
|
|
|
|
|
'user_id' => request()->cookie('uid'),
|
|
|
|
|
'openid' => $openid,
|
|
|
|
|
'nickname' => $nickname,
|
2022-12-02 11:16:57 +08:00
|
|
|
'access_token' => $info['access_token'],
|
|
|
|
|
'refresh_token' => $info['refresh_token'],
|
|
|
|
|
'expires_in' => $info['expires_in'],
|
2022-08-19 19:48:37 +08:00
|
|
|
'login_time' => time(),
|
2022-12-02 11:16:57 +08:00
|
|
|
'expiretime' => time() + $info['expires_in'],
|
2022-08-19 19:48:37 +08:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
if (UserThird::create($third)) {
|
|
|
|
|
return $this->redirectUrl();
|
|
|
|
|
} else {
|
|
|
|
|
return $this->error('绑定异常');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $this->error('当前用户已被其他账户绑定!');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 跳转URL
|
2022-11-28 19:11:12 +08:00
|
|
|
* @return Response
|
2022-08-19 19:48:37 +08:00
|
|
|
*/
|
2022-11-28 19:11:12 +08:00
|
|
|
protected function redirectUrl(): Response
|
2022-08-19 19:48:37 +08:00
|
|
|
{
|
|
|
|
|
$referer = request()->cookie('redirectUrl', '/');
|
|
|
|
|
|
|
|
|
|
if (preg_match("/(user\/login|user\/register|user\/logout)/i", $referer)) {
|
|
|
|
|
$referer = '/';
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-19 14:32:30 +08:00
|
|
|
request()->cookie('redirectUrl', null, 1);
|
2022-08-19 19:48:37 +08:00
|
|
|
return $this->redirect($referer);
|
|
|
|
|
}
|
|
|
|
|
}
|