[接口]鉴权authToken用户登录login-注册register-退出logout, 并将用户信息保存到redis中
This commit is contained in:
114
server/app/api/cache/UserCache.php
vendored
Normal file
114
server/app/api/cache/UserCache.php
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\api\cache;
|
||||
|
||||
use support\think\Cache;
|
||||
|
||||
/**
|
||||
* API 用户信息 Redis 缓存
|
||||
* key = base64(user_id),value = 加密后的用户信息 JSON
|
||||
*/
|
||||
class UserCache
|
||||
{
|
||||
private static function prefix(): string
|
||||
{
|
||||
return config('api.user_cache_prefix', 'api:user:');
|
||||
}
|
||||
|
||||
private static function expire(): int
|
||||
{
|
||||
return (int) config('api.user_cache_expire', 604800);
|
||||
}
|
||||
|
||||
private static function encryptKey(): string
|
||||
{
|
||||
$key = config('api.user_encrypt_key', 'dafuweng_api_user_cache_key_32');
|
||||
return str_pad($key, 32, '0', STR_PAD_RIGHT);
|
||||
}
|
||||
|
||||
/** 加密 */
|
||||
public static function encrypt(string $data): string
|
||||
{
|
||||
$key = self::encryptKey();
|
||||
$iv = substr(md5($key), 0, 16);
|
||||
return base64_encode(openssl_encrypt($data, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv));
|
||||
}
|
||||
|
||||
/** 解密 */
|
||||
public static function decrypt(string $data): string
|
||||
{
|
||||
$key = self::encryptKey();
|
||||
$iv = substr(md5($key), 0, 16);
|
||||
$dec = openssl_decrypt(base64_decode($data, true), 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
|
||||
return $dec !== false ? $dec : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入用户信息到 Redis
|
||||
* @param int $userId
|
||||
* @param array $userInfo 从数据库读取的用户信息(可含敏感字段,会加密存储)
|
||||
*/
|
||||
public static function setUser(int $userId, array $userInfo): bool
|
||||
{
|
||||
$key = self::prefix() . base64_encode((string) $userId);
|
||||
$value = self::encrypt(json_encode($userInfo));
|
||||
return Cache::set($key, $value, self::expire());
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 Redis 读取用户信息
|
||||
* @return array 解密后的用户信息,不存在或失败返回空数组
|
||||
*/
|
||||
public static function getUser(int $userId): array
|
||||
{
|
||||
$key = self::prefix() . base64_encode((string) $userId);
|
||||
$value = Cache::get($key);
|
||||
if ($value === null || $value === '') {
|
||||
return [];
|
||||
}
|
||||
$dec = self::decrypt($value);
|
||||
if ($dec === '') {
|
||||
return [];
|
||||
}
|
||||
$data = json_decode($dec, true);
|
||||
return is_array($data) ? $data : [];
|
||||
}
|
||||
|
||||
/** 删除用户缓存 */
|
||||
public static function deleteUser(int $userId): bool
|
||||
{
|
||||
$key = self::prefix() . base64_encode((string) $userId);
|
||||
return Cache::delete($key);
|
||||
}
|
||||
|
||||
/** user-token 黑名单前缀(退出登录后使 token 失效) */
|
||||
private static function blacklistPrefix(): string
|
||||
{
|
||||
return config('api.user_cache_prefix', 'api:user:') . 'token_blacklist:';
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 user-token 加入黑名单(退出登录)
|
||||
* @param string $token 完整 token 字符串
|
||||
* @param int $ttl 黑名单过期时间(秒),建议为 token 剩余有效期
|
||||
*/
|
||||
public static function addTokenToBlacklist(string $token, int $ttl = 86400): bool
|
||||
{
|
||||
if ($ttl <= 0) {
|
||||
return true;
|
||||
}
|
||||
$key = self::blacklistPrefix() . md5($token);
|
||||
return Cache::set($key, '1', $ttl);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查 user-token 是否在黑名单中(已退出)
|
||||
*/
|
||||
public static function isTokenBlacklisted(string $token): bool
|
||||
{
|
||||
$key = self::blacklistPrefix() . md5($token);
|
||||
$val = Cache::get($key);
|
||||
return $val !== null && $val !== '';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user