fix: dual-write token (DB+cache) and dual-read with fallback, works with or without SQL migration

This commit is contained in:
2026-05-20 17:54:21 +08:00
parent f639ef2fbb
commit 8d015fa962
@@ -16,7 +16,7 @@ class AssetAppController extends BaseApiController
const TOKEN_EXPIRE = 86400 * 7;
/**
* @notes 通过 token 获取当前用户(数据库校验
* @notes 通过 token 获取当前用户(DB 优先,file cache 兜底
*/
private function getAssetUser(): ?AssetUser
{
@@ -24,11 +24,28 @@ class AssetAppController extends BaseApiController
if (empty($token)) {
return null;
}
$user = AssetUser::where('token', $token)
->where('token_expire_time', '>', time())
->where('status', 1)
->find();
return $user ?: null;
// 方式1: 从数据库 token 字段查找(需要已执行 asset_user_token.sql
try {
$user = AssetUser::where('token', $token)
->where('token_expire_time', '>', time())
->where('status', 1)
->find();
if ($user) {
return $user;
}
} catch (\Throwable $e) {
// token 字段不存在时忽略,走 cache 兜底
}
// 方式2: 从 file cache 查找(兼容旧登录 / 未执行 SQL 迁移)
$userId = cache('asset_token_' . $token);
if ($userId) {
$user = AssetUser::where('id', $userId)->where('status', 1)->find();
return $user ?: null;
}
return null;
}
/**
@@ -56,11 +73,20 @@ class AssetAppController extends BaseApiController
return $this->fail('密码错误');
}
// 生成 token 并持久化到数据库
// 生成 token 并双写(DB + cache 兜底)
$token = md5($user->id . time() . uniqid('asset', true));
$user->token = $token;
$user->token_expire_time = time() + self::TOKEN_EXPIRE;
$user->save();
// 写入 file cache(始终可用)
cache('asset_token_' . $token, $user->id, self::TOKEN_EXPIRE);
// 尝试写入数据库(需要已执行 SQL 迁移)
try {
$user->token = $token;
$user->token_expire_time = time() + self::TOKEN_EXPIRE;
$user->save();
} catch (\Throwable $e) {
// token 字段不存在时忽略,cache 已经写入
}
return $this->success('登录成功', [
'token' => $token,