338 lines
7.6 KiB
PHP
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());
|
|
}
|
|
}
|