Files

284 lines
8.4 KiB
PHP
Raw Permalink Normal View History

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;
2023-06-25 16:56:18 +08:00
use app\common\exception\OperateException;
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
/**
* 禁止登录重复
2022-08-19 19:48:37 +08:00
* @var array
*/
public array $repeatLogin = ['register'];
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
2023-06-19 14:32:30 +08:00
* @throws InvalidArgumentException
2023-06-25 16:56:18 +08:00
* @throws ModelNotFoundException
* @throws OperateException
2022-08-19 19:48:37 +08:00
*/
public function callback()
{
try {
$this->oauth = $this->oType();
} catch (\Exception $e) {
return $this->error($e->getMessage());
}
2023-06-25 16:56:18 +08:00
$user = $this->oauth->getUserInfo();
2023-06-19 14:32:30 +08:00
if (!empty($user) && !UserTokenService::isLogin()) {
return $this->register($user, $this->type);
2023-06-19 14:32:30 +08:00
} else if (UserTokenService::isLogin()) { // 绑定用户
return $this->doBind($user, $this->type);
2022-08-19 19:48:37 +08:00
}
2023-06-25 16:56:18 +08:00
return $this->error('登录失败');
2022-08-19 19:48:37 +08:00
}
/**
* 用户注册操作
* @param array $info
2023-06-25 16:56:18 +08:00
* @param string $type
2022-11-28 19:11:12 +08:00
* @return Response
* @throws DataNotFoundException
* @throws DbException
2023-06-25 16:56:18 +08:00
* @throws InvalidArgumentException
2022-11-28 19:11:12 +08:00
* @throws ModelNotFoundException
2023-06-25 16:56:18 +08:00
* @throws OperateException
2022-08-19 19:48:37 +08:00
*/
2023-06-25 16:56:18 +08:00
protected function register(array $info, string $type): Response
2022-08-19 19:48:37 +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();
$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,
'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(),
'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-07-03 10:08:34 +08:00
return $this->redirect("/index/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();
2023-06-25 16:56:18 +08:00
if (empty($result['email']) || empty($result['pwd'])) {
return $this->error('解除绑定需要设置邮箱和密码!');
}
2022-08-19 19:48:37 +08:00
2023-06-25 16:56:18 +08:00
$where['type'] = $this->type;
$where['user_id'] = request()->userId;
if (UserThird::where($where)->delete()) {
return $this->success('解除绑定成功!');
2022-08-19 19:48:37 +08:00
}
return $this->error();
}
/**
* 用户绑定操作实例
* @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
*/
protected function doBind(array $info = [], string $type = null)
2022-08-19 19:48:37 +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,
'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(),
'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);
}
}