post('user_id'); $timestamp = (int)$request->post('timestamp'); $signature = $request->post('signature'); $systemCode = $request->post('system_code'); // 参数验证 if (empty($userId) || empty($timestamp) || empty($signature)) { return $this->error('参数不完整', 400); } // 获取配置 $secret = config('system_auth.shared_secret'); $expire = config('system_auth.signature_expire', 600); // 验证时间戳(10分钟有效期) if (!SystemAuth::verifyTimestamp($timestamp, $expire)) { return $this->error('请求已过期', 401); } // 验证签名 if (!SystemAuth::verifySignature($userId, $timestamp, $signature, $secret)) { return $this->error('签名验证失败', 401); } // 查找用户 $user = User::find($userId); if (!$user) { return $this->error('用户不存在', 404); } // 验证系统(如果提供了 system_code) $system = null; if ($systemCode) { $system = Systems::where('code', $systemCode)->first(); if (!$system) { return $this->error('系统不存在', 404); } } // 获取 corp_abbr(优先从请求参数获取,否则通过用户 corp_id 查询) $corpAbbr = $request->post('corp_abbr'); if (!$corpAbbr && $user->corp_id) { $corp = \app\common\model\Corp::find($user->corp_id); $corpAbbr = $corp ? $corp->abbr : ''; } // 构建 JWT payload $payload = $this->buildJwtPayload($user, $system); // 生成 access_token $jwt = new Jwt(); $token = $jwt->generateToken($payload); // 生成 refresh_token $refreshToken = $this->generateRefreshToken($user->id, $systemCode ?? ''); // 获取 home_url $homeUrl = $system ? $this->getHome($system->id, $payload) : ''; // 记录 token 到 Redis 和 MySQL $this->recordUserToken($user->id, $token, $systemCode ?? ''); // 构建用户信息(去除敏感信息) $userInfo = [ 'id' => $user->id, 'sn' => $user->sn ?? '', 'name' => $user->name ?? '', 'avatar' => $user->avatar ?? '', 'phone' => $user->phone ?? '', 'email' => $user->email ?? '', 'sex' => $user->sex ?? '', 'position' => $user->position ?? '', 'status' => $user->status ?? 1, 'corp_id' => $user->corp_id, ]; return $this->success([ 'access_token' => $token, 'refresh_token' => $refreshToken, 'expires_in' => config('jwt.jwt_expiration'), 'system_code' => $systemCode ?? '', 'corp_abbr' => $corpAbbr ?? '', 'login_type' => 'system', 'home_url' => $homeUrl, 'user_info' => $userInfo, ], '认证成功'); } /** * 构建 JWT payload */ private function buildJwtPayload(User $user, ?Systems $system): array { $payload = [ 'user_id' => $user->id, 'sn' => $user->sn ?? '', 'name' => $user->name ?? '', 'iat' => time(), 'exp' => time() + config('jwt.jwt_expiration'), ]; if ($system) { $payload['system_code'] = $system->code; $payload['system_id'] = $system->id; } return $payload; } /** * 生成 refresh_token */ private function generateRefreshToken(int $userId, string $systemCode): string { $refreshToken = bin2hex(random_bytes(32)); // 存储到 Redis $key = "refresh_token:{$refreshToken}"; $expire = config('jwt.jwt_refresh_token_expiration'); Redis::setex($key, $expire, json_encode([ 'user_id' => $userId, 'system_code' => $systemCode, ])); return $refreshToken; } /** * 获取用户首页地址 */ private function getHome(int $systemId, array $payload): string { // 简单实现,可以根据实际需求调整 return ''; } /** * 记录用户token到 Redis 和 MySQL */ private function recordUserToken(int $userId, string $token, string $systemCode): void { $request = request(); $ip = $request ? $request->getRealIp() : ''; $ua = $request ? $request->header('user-agent', '') : ''; $now = time(); $expireAt = $now + config('jwt.jwt_expiration'); // Redis Set 用户token集合 Redis::sAdd("user_tokens:{$userId}:{$systemCode}", $token); Redis::expire("user_tokens:{$userId}:{$systemCode}", config('jwt.jwt_expiration')); // Redis Hash token元信息 $meta = [ 'system_code' => $systemCode, 'login_ip' => $ip, 'user_agent' => $ua, 'login_time' => $now, 'expired_at' => $expireAt, ]; Redis::hMSet("user_token_meta:{$token}", $meta); Redis::expire("user_token_meta:{$token}", config('jwt.jwt_expiration')); // MySQL 持久化 \app\common\model\UserTokenLog::create([ 'user_id' => $userId, 'token' => $token, 'system_code' => $systemCode, 'login_ip' => $ip, 'user_agent' => $ua, 'expired_at' => date('Y-m-d H:i:s', $expireAt), ]); } }