Files
swiftadmin/app/common/library/Auth.php

302 lines
8.1 KiB
PHP
Raw 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\common\library;
2022-11-28 19:11:12 +08:00
use app\common\model\system\UserLog;
2022-08-19 19:48:37 +08:00
use system\Random;
use support\Response;
use think\facade\Cache;
use app\common\model\system\User as UserModel;
use Webman\Event\Event;
class Auth
{
/**
* token令牌
* @var string
*/
2022-11-28 19:11:12 +08:00
public string $token;
2022-08-19 19:48:37 +08:00
/**
* 用户数据
* @var object|array
*/
2022-11-28 19:11:12 +08:00
public mixed $userData;
2022-08-19 19:48:37 +08:00
/**
* 保活时间
2022-11-28 19:11:12 +08:00
* @var int
2022-08-19 19:48:37 +08:00
*/
2022-11-28 19:11:12 +08:00
protected int $keepTime = 604800;
2022-08-19 19:48:37 +08:00
/**
* 错误信息
* @var string
*/
2022-11-28 19:11:12 +08:00
protected string $_error = '';
2022-08-19 19:48:37 +08:00
/**
* @var object 对象实例
*/
2022-11-28 19:11:12 +08:00
protected static $instance;
2022-08-19 19:48:37 +08:00
/**
* 类构造函数
* class constructor.
*/
public function __construct($config = [])
{
$this->keepTime = config('session.cookie_lifetime');
}
/**
* 初始化
* @access public
* @param array $options 参数
* @return object
*/
public static function instance(array $options = [])
{
if (is_null(self::$instance)) {
self::$instance = new static($options);
}
// 返回实例
return self::$instance;
}
/**
* 用户注册
* @param array $post
2022-11-28 19:11:12 +08:00
* @return bool
2022-08-19 19:48:37 +08:00
* @throws \Psr\SimpleCache\InvalidArgumentException
* @throws \think\db\exception\DbException
*/
public function register(array $post)
{
if (!saenv('user_status')) {
$this->setError('暂未开放注册!');
return false;
}
/**
* 禁止批量注册
*/
2022-08-23 11:11:42 +08:00
$where[] = ['create_ip', '=', ip2long(request()->getRealIp())];
2022-08-19 19:48:37 +08:00
$where[] = ['create_time', '>', linux_extime(1)];
$totalMax = UserModel::where($where)->count();
if ($totalMax >= saenv('user_register_second')) {
$this->setError('当日注册量已达到上限');
return false;
}
// 过滤用户信息
if (isset($post['nickname']) && UserModel::getByNickname($post['nickname'])) {
$this->setError('当前用户名已被占用!');
return false;
}
if (isset($post['email']) && UserModel::getByEmail($post['email'])) {
$this->setError('当前邮箱已被占用!');
return false;
}
if (isset($post['mobile']) && UserModel::getByMobile($post['mobile'])) {
$this->setError('当前手机号已被占用!');
return false;
}
try {
/**
* 是否存在邀请注册
*/
$post['invite_id'] = $this->getToken('inviter');
if (isset($post['pwd']) && $post['pwd']) {
$post['salt'] = Random::alpha();
$post['pwd'] = encryptPwd($post['pwd'], $post['salt']);
}
2022-11-28 19:11:12 +08:00
$this->userData = UserModel::create($post);
2022-08-19 19:48:37 +08:00
2022-11-28 19:11:12 +08:00
return $this->responseToken($this->userData);
2022-08-19 19:48:37 +08:00
} catch (\Throwable $th) {
$this->setError($th->getMessage());
return false;
}
}
/**
* 用户检测登录
* @param string $nickname
* @param string $pwd
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function login(string $nickname = '', string $pwd = '')
{
// 支持邮箱或手机登录
if (filter_var($nickname, FILTER_VALIDATE_EMAIL)) {
$where[] = ['email', '=', htmlspecialchars(trim($nickname))];
} else {
$where[] = ['mobile', '=', htmlspecialchars(trim($nickname))];
}
2022-11-28 19:11:12 +08:00
$this->userData = UserModel::where($where)->find();
2022-08-19 19:48:37 +08:00
2022-11-28 19:11:12 +08:00
if (!empty($this->userData)) {
$uPwd = encryptPwd($pwd, $this->userData['salt']);
if ($this->userData['pwd'] !== $uPwd) {
2022-08-19 19:48:37 +08:00
$this->setError('用户名或密码错误');
2022-11-28 19:11:12 +08:00
UserLog::write($this->getError(), $this->userData->nickname, $this->userData->id);
2022-08-19 19:48:37 +08:00
return false;
}
2022-11-28 19:11:12 +08:00
if (!$this->userData['status']) {
2022-08-19 19:48:37 +08:00
$this->setError('用户异常或未审核,请联系管理员');
2022-11-28 19:11:12 +08:00
UserLog::write($this->getError(), $this->userData->nickname, $this->userData->id);
2022-08-19 19:48:37 +08:00
return false;
}
// 更新登录数据
$userUpdate = [
2022-11-28 19:11:12 +08:00
'id' => $this->userData['id'],
2022-08-19 19:48:37 +08:00
'login_time' => time(),
2022-08-23 11:11:42 +08:00
'login_ip' => request()->getRealIp(),
2022-11-28 19:11:12 +08:00
'login_count' => $this->userData['login_count'] + 1,
2022-08-19 19:48:37 +08:00
];
if (UserModel::update($userUpdate)) {
2022-11-28 19:11:12 +08:00
Event::emit('userLoginSuccess', $this->userData);
UserLog::write('登录成功', $this->userData->nickname, $this->userData->id, 1);
return $this->responseToken($this->userData);
2022-08-19 19:48:37 +08:00
}
}
$this->setError('您登录的用户不存在');
return false;
}
/**
* 验证是否登录
* @return bool
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function isLogin(): bool
{
$token = $this->getToken();
if (!$token) {
return false;
}
$uid = $this->checkToken($token);
if (!empty($uid)) {
$this->token = $token;
2022-11-28 19:11:12 +08:00
$this->userData = UserModel::with('group')->find($uid);
2022-08-19 19:48:37 +08:00
return true;
}
return false;
}
/**
* 退出登录
* @return void
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
public function logout()
{
Cache::delete($this->token);
}
/**
*
* 返回前端令牌
2022-11-28 19:11:12 +08:00
* @param mixed $userData
2022-08-19 19:48:37 +08:00
* @param bool $token
* @return mixed
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
2022-11-28 19:11:12 +08:00
public function responseToken($userData, bool $token = false)
2022-08-19 19:48:37 +08:00
{
2022-11-28 19:11:12 +08:00
$this->token = $token ? $this->getToken() : $this->buildToken($userData['id']);
2022-08-19 19:48:37 +08:00
$response = response();
2022-11-28 19:11:12 +08:00
$response->cookie('uid', $userData['id'],$this->keepTime, '/');
2022-08-19 19:48:37 +08:00
$response->cookie('token', $this->token,$this->keepTime, '/');
2022-11-28 19:11:12 +08:00
$response->cookie('nickname', $userData['nickname'],$this->keepTime, '/');
Cache::set($this->token, $userData['id'], $this->keepTime);
Event::emit("userLoginSuccess", $userData);
2022-08-19 19:48:37 +08:00
return $response;
}
/**
* 生成token
* @access protected
* @param $id
* @return string
*/
protected function buildToken($id): string
{
return md5(Random::alpha(16) . $id);
}
/**
* 获取token
* @return array|string|null
*/
public function getToken($token = 'token')
{
return request()->header($token, input($token, request()->cookie($token)));
}
/**
* 校验token
* @access protected
* @param $token
2022-11-28 19:11:12 +08:00
* @return void
2022-08-19 19:48:37 +08:00
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
public function checkToken($token)
{
2022-11-28 19:11:12 +08:00
$user_id = Cache::get($token);
return $user_id ?? false;
2022-08-19 19:48:37 +08:00
}
/**
* 获取最后产生的错误
* @return string
*/
public function getError(): string
{
return $this->_error;
}
/**
* 设置错误
* @param string $error 信息信息
2022-11-28 19:11:12 +08:00
* @return void
2022-08-19 19:48:37 +08:00
*/
2022-11-28 19:11:12 +08:00
protected function setError(string $error): void
2022-08-19 19:48:37 +08:00
{
$this->_error = $error;
}
}