drag-create-api/app/common/model/Token.php
2023-06-25 08:51:24 +08:00

338 lines
7.6 KiB
PHP

<?php
namespace app\common\model;
use app\BaseModel;
use app\common\arw\adjfut\src\Exception\ErrorMsg;
use app\common\exception\LoginTimeOut;
use app\common\model\User\User;
use think\facade\Request;
use think\helper\Arr;
use think\model\relation\HasOne;
/**
* Token
*
* @date 2022-12-27
* @example
* @author admin
* @since 1.0.0
*/
class Token extends BaseModel
{
// 设置主键名
protected $pk = 'token_guid';
// 设置废弃字段
protected $disuse = [];
// 设置字段信息
protected $schema = [
'token_id' => 'int',
'token_guid' => 'string',
'user_guid' => 'string',
'token_menu' => 'json',
'token_api' => 'json',
'token_exp_time' => 'datetime',
'token_content' => 'string',
'token_create_time' => 'datetime',
'token_update_time' => 'datetime',
];
// json数据字段
protected $json = ['token_menu', 'token_api'];
// 设置JSON数据返回数组
protected $jsonAssoc = true;
// 开启自动写入时间戳字段
protected $autoWriteTimestamp = 'datetime';
// 创建时间
protected $createTime = 'token_create_time';
// 修改时间
protected $updateTime = 'token_update_time';
/**
* 当前用户
*
* @var User
*/
private static $user = null;
/**
* 当前model
*
* @var self
*/
private static $current = null;
/**
* 用户
*
* @date 2022-02-22
* @example
* @author admin
* @since 1.0.0
*/
public function user(): hasOne
{
return $this->hasOne(User::class, 'user_guid', 'user_guid');
}
/**
* 设置过期时间
*
* @param mixed $value
* @date 2022-02-22
* @example
* @author admin
* @since 1.0.0
*/
public function setTokenExpTimeAttr($value): string
{
return date('Y-m-d H:i:s', $value);
}
/**
* 判断是否过期
*
* @return boolean
* @date 2022-12-27
* @example
* @author admin
* @since 1.0.0
*/
public function getIsExpAttr(): bool
{
return time() >= $this->token_exp_timestamp;
}
/**
* 获取过期时间戳
*
* @return integer
* @date 2022-12-27
* @example
* @author admin
* @since 1.0.0
*/
public function getTokenExpTimestampAttr(): int
{
return strtotime($this->token_exp_time);
}
/**
* 新增前
*
* @param self $model
* @return void
* @date 2022-12-27
* @example
* @author admin
* @since 1.0.0
*/
public static function onBeforeInsert(self $model): void
{
$model->token_content = $model->generateContent();
$model->token_guid = self::generateGuid();
}
/**
* 登陆
* 如果当前存在有效token 更新过期时间
* 如果token已过期 更新token和过期时间
* 如果不存在token 新增数据
*
* @param string $guid 用户id
* @param array $options 配置项
* @param int $options[expTime] 过期时间(时间戳) 不传默认两小时
* @param array $options[menu] 菜单
* @param int $options[api] 接口
* @date 2022-02-22
* @example
* @author admin
* @since 1.0.0
*/
public static function login(string $guid, array $options = []): self
{
$expTime = 0;
$menu = [];
$api = [];
if (is_array($options)) {
$expTime = Arr::get($options, 'expTime', 0);
$menu = Arr::get($options, 'menu', []);
$api = Arr::get($options, 'api', []);
}
if ($expTime == 0) {
$expTime = time() + (24 * 60 * 60);
}
$data = [
'token_exp_time' => $expTime
];
if ($menu) {
$data['token_menu'] = $menu;
}
if ($api) {
$data['token_api'] = $api;
}
/**
* @var Token
*/
$model = self::where([
'user_guid' => $guid,
])->find();
// 数据不存在
if (!$model) {
return self::create($data + [
'user_guid' => $guid,
]);
}
// token已过期
if ($model->is_exp) {
$data['token_content'] = $model->generateContent($model);
}
$model->save($data);
return $model;
}
/**
* 登出
*
* @date 2022-03-15
* @example
* @author admin
* @since 1.0.0
*/
public static function logout(): void
{
self::getCurrent()->delete();
}
/**
* 获取请求token
*
* @date 2022-02-22
* @example
* @author admin
* @since 1.0.0
*/
public static function getRequestToken(): string
{
$tokenKey = 'token';
$token = '';
if (!$token && isset($_GET[$tokenKey])) {
$token = $_GET[$tokenKey];
}
if (!$token && isset($_POST[$tokenKey])) {
$token = $_POST[$tokenKey];
}
if (!$token && Request::param($tokenKey)) {
$token = Request::param($tokenKey);
}
if (!$token && Request::header($tokenKey)) {
$token = Request::header($tokenKey);
}
return $token;
}
/**
* 获取当前用户信息
*
* @date 2022-02-22
* @example
* @author admin
* @since 1.0.0
*/
public static function getCurrentUser(): User
{
if (!self::$user) {
$model = self::getCurrent();
self::$user = $model->user;
if (!self::$user) {
throw new ErrorMsg("用户不存在", 1);
}
}
return self::$user;
}
/**
* 获取当前有效token
*
* @date 2022-02-28
* @example
* @author admin
* @since 1.0.0
*/
public static function getCurrent(): self
{
if (!self::$current) {
$content = self::getRequestToken();
if (!$content) {
throw new LoginTimeOut("缺少token", 1);
}
$model = self::where([
'token_content' => $content,
])->find();
if (!$model) {
throw new LoginTimeOut("未登录", 1);
}
if ($model->is_exp) {
throw new LoginTimeOut("登录超时", 1);
}
self::$current = $model;
}
return self::$current;
}
/**
* 判断是否登录
*
* @date 2022-05-14
* @example
* @author admin
* @since 1.0.0
*/
public static function isLogin(): bool
{
try {
self::getCurrent();
return true;
} catch (LoginTimeOut $th) {
return false;
}
}
/**
* 延长token
* 过期前30分钟才会延期
*
* @date 2022-02-28
* @example
* @author admin
* @since 1.0.0
*/
public static function delay(): void
{
try {
// 半小时
$delay = (60 * 30);
$model = self::getCurrent();
$token_exp_time = $model->token_exp_timestamp;
if (time() >= ($token_exp_time - $delay)) {
self::login($model->user_guid);
}
} catch (LoginTimeOut $th) {
}
}
/**
* 生成token内容
*
* @date 2022-02-22
* @example
* @author admin
* @since 1.0.0
*/
private function generateContent(): string
{
return md5(join('-', [
$this->token_exp_time,
$this->user_guid,
]) . time());
}
}