chore: 重写初始提交(清空历史,整理后全量提交)
This commit is contained in:
@@ -0,0 +1,226 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: ywxapp<admin@ywxapp.cn>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ywxapp\library;
|
||||
|
||||
use think\App;
|
||||
use think\exception\HttpException;
|
||||
use think\facade\Db;
|
||||
use think\facade\Event;
|
||||
use think\facade\Validate;
|
||||
use ywxapp\library\Result;
|
||||
use ywxapp\model\BackendAdmin as AdminModel;
|
||||
use ywxapp\service\JwtService;
|
||||
use ywxapp\utils\Random;
|
||||
|
||||
/**
|
||||
* 后台(管理员)鉴权类,继承前台 Auth,仅重写差异钩子与业务逻辑。
|
||||
*
|
||||
* 差异点:
|
||||
* - 模型:Backend 模型(主键 id)
|
||||
* - 角色字段:roles;权限集:getPermissionNames()
|
||||
* - 登录事件:user_login_successed
|
||||
* - 登出:不清整个 session(仅清 token),保持与原 Backend 行为一致
|
||||
* - 登录/注册/改密:后台业务逻辑(查 Backend 表)
|
||||
*/
|
||||
class AdminAuth extends Auth
|
||||
{
|
||||
/**
|
||||
* 超级管理员
|
||||
*/
|
||||
protected $isSuperAdmin = false;
|
||||
|
||||
/**
|
||||
* 超级管理员
|
||||
*/
|
||||
private $superAdmin = 1;
|
||||
|
||||
/**
|
||||
* 允许查询的字段(后台)
|
||||
* @var array
|
||||
*/
|
||||
protected $allowFields = ['id', 'account', 'nickname', 'roles', 'avatar', 'score'];
|
||||
|
||||
/**
|
||||
* 构造方法
|
||||
* @param App $app
|
||||
*/
|
||||
public function __construct(App $app, $options = [])
|
||||
{
|
||||
parent::__construct($app, $options);
|
||||
$this->isAdmin = true; // 标记后台管理员上下文,供 tryLoginByToken 做 isAdmin 一致性校验
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回管理员模型类(主键为 id)
|
||||
*/
|
||||
protected function getUserModel(): string
|
||||
{
|
||||
return AdminModel::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* 后台角色取自 roles 字段(前台 Auth 默认取 groups,此处重写)
|
||||
*/
|
||||
protected function resolveRoles($info)
|
||||
{
|
||||
return $info->roles ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 管理员权限取自模型方法(后台式权限集)
|
||||
*/
|
||||
protected function resolvePowers($info): array
|
||||
{
|
||||
return $info->getPermissionNames();
|
||||
}
|
||||
|
||||
/**
|
||||
* 管理员不存在时的错误提示
|
||||
*/
|
||||
protected function notFoundMessage($id): string
|
||||
{
|
||||
return "AdminId:$id is incorrect";
|
||||
}
|
||||
|
||||
/**
|
||||
* 管理员登录成功后触发事件
|
||||
*/
|
||||
protected function afterLogin($info): void
|
||||
{
|
||||
Event::trigger('user_login_successed', $this->info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 后台登出:仅清 token(不清整个 session),保持与原 Backend 行为一致
|
||||
*/
|
||||
protected function afterLogout(): void {}
|
||||
|
||||
/**
|
||||
* 添加管理员(后台).
|
||||
*
|
||||
* @param string $username 用户名
|
||||
* @param string $password 密码
|
||||
* @param array $extend 扩展参数
|
||||
* @return void
|
||||
*/
|
||||
public function register($account = '', $password = '', $email = '', $mobile = '', $extend = [])
|
||||
|
||||
{
|
||||
AdminModel::ensureSchema(); // 后台核心表自愈(缺表/缺列兜底)
|
||||
if (AdminModel::getByAccount($account)) {
|
||||
Result::instance()->error('Account already exist');
|
||||
}
|
||||
$data = [
|
||||
'password' => password_hash($password ? $password : Random::alpha(6), PASSWORD_DEFAULT, ['cost' => 12]),
|
||||
'status' => 0,
|
||||
't1' => $account,
|
||||
];
|
||||
$field = Validate::is($account, 'email') ? 'email' : (Validate::is($account, 'mobile') ? 'mobile' : 'account');
|
||||
$data[$field] = $account;
|
||||
$data = array_merge($data, $extend);
|
||||
$params = Event::trigger('AdminBeforeRegister', $data, true);
|
||||
$data = array_merge($data, $params);
|
||||
Db::startTrans();
|
||||
try {
|
||||
$info = AdminModel::create($data);
|
||||
$this->info = AdminModel::find($info->id);
|
||||
Event::trigger('AdminAfterRegister', $this->info);
|
||||
Db::commit();
|
||||
$newClaims = [
|
||||
'uid' => $info->id,
|
||||
'isAdmin' => true,
|
||||
'account' => $info->account,
|
||||
];
|
||||
$tokens = JwtService::instance()->createToken($newClaims);
|
||||
$this->persistTokens($tokens);
|
||||
} catch (\think\Exception $e) {
|
||||
Db::rollback();
|
||||
Result::instance()->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 管理员登录(后台).
|
||||
*
|
||||
* @param string $account 账号,用户名、邮箱、手机号
|
||||
* @param string $password 密码
|
||||
* @return void
|
||||
*/
|
||||
public function login($account, $password, $isAuthPass = true)
|
||||
{
|
||||
AdminModel::ensureSchema(); // 后台核心表自愈(缺表/缺列兜底)
|
||||
$field = Validate::is($account, 'email') ? 'email' : (Validate::regex(
|
||||
$account,
|
||||
'/^1\d{10}$/'
|
||||
) ? 'mobile' : 'account');
|
||||
$info = AdminModel::where([$field => $account])->find();
|
||||
if (! $info) {
|
||||
Result::instance()->error('Account is incorrect');
|
||||
}
|
||||
if ($info->status != 1) {
|
||||
Result::instance()->error('Account is locked');
|
||||
}
|
||||
$info->resetPassword($password);
|
||||
// 验证密码(直接使用库中存储的哈希,禁止先 resetPassword)
|
||||
if (! $info->checkPassword($password)) {
|
||||
$info->recordLoginFail($this->app->request->ip()); // 记录失败
|
||||
Result::instance()->error('密码错误', 4011);
|
||||
}
|
||||
$info->recordLoginSuccess();
|
||||
$newClaims = [
|
||||
'uid' => $info->id,
|
||||
'isAdmin' => true,
|
||||
'role' => 'admin',
|
||||
'account' => $info->account,
|
||||
];
|
||||
$tokens = JwtService::instance()->createToken($newClaims);
|
||||
$this->persistTokens($tokens);
|
||||
$this->initUser($info->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改密码(后台)
|
||||
* @param string $newpassword 新密码
|
||||
* @param string $oldpassword 旧密码
|
||||
* @param bool $ignoreoldpassword 忽略旧密码
|
||||
* @return boolean
|
||||
*/
|
||||
public function changepwd($newpassword, $oldpassword = '', $ignoreoldpassword = false)
|
||||
{
|
||||
if (! $this->_logined) {
|
||||
$this->setError('You are not logged in');
|
||||
return false;
|
||||
}
|
||||
//判断旧密码是否正确
|
||||
if ($this->_user->password == $this->getEncryptPassword($oldpassword, $this->_user->salt) || $ignoreoldpassword) {
|
||||
Db::startTrans();
|
||||
try {
|
||||
$salt = Random::alnum();
|
||||
$newpassword = $this->getEncryptPassword($newpassword, $salt);
|
||||
$this->_user->save(['loginfailure' => 0, 'password' => $newpassword, 'salt' => $salt]);
|
||||
|
||||
Token::clear($this->_user->uid);
|
||||
//修改密码成功的事件
|
||||
Hook::listen("user_changepwd_successed", $this->_user);
|
||||
Db::commit();
|
||||
} catch (Exception $e) {
|
||||
Db::rollback();
|
||||
$this->setError($e->getMessage());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
$this->setError('Password is incorrect');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user