AuthController.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. <?php
  2. namespace App\Module\OpenAPI\Controllers;
  3. use App\Module\OpenAPI\Services\AuthService;
  4. use App\Module\OpenAPI\Services\OpenApiService;
  5. use App\Module\OpenAPI\Validators\AuthValidator;
  6. use Illuminate\Http\Request;
  7. use Illuminate\Http\JsonResponse;
  8. /**
  9. * 认证控制器
  10. */
  11. class AuthController
  12. {
  13. /**
  14. * @var AuthService
  15. */
  16. protected AuthService $authService;
  17. /**
  18. * @var OpenApiService
  19. */
  20. protected OpenApiService $openApiService;
  21. /**
  22. * @var AuthValidator
  23. */
  24. protected AuthValidator $authValidator;
  25. public function __construct(
  26. AuthService $authService,
  27. OpenApiService $openApiService,
  28. AuthValidator $authValidator
  29. ) {
  30. $this->authService = $authService;
  31. $this->openApiService = $openApiService;
  32. $this->authValidator = $authValidator;
  33. }
  34. /**
  35. * 获取访问令牌
  36. *
  37. * @param Request $request
  38. * @return JsonResponse
  39. */
  40. public function token(Request $request): JsonResponse
  41. {
  42. $startTime = microtime(true);
  43. // 初始化请求日志记录器
  44. $requestLogger = new \App\Module\System\Services\RequestLogger($request);
  45. $requestLogger->setRouter("openapi/auth/token");
  46. try {
  47. // 使用标准验证系统
  48. $validation = new \App\Module\OpenAPI\Validations\TokenRequestValidation($request->all());
  49. $validation->validate();
  50. if ($validation->isFail()) {
  51. // 记录验证失败和运行时间
  52. $requestLogger->setError('参数验证失败: ' . json_encode($validation->getErrors()));
  53. $requestLogger->setRunTime($startTime);
  54. return $this->errorResponse('参数验证失败', $validation->getErrors(), 400);
  55. }
  56. $data = $validation->getSafeData();
  57. $grantType = $data['grant_type'];
  58. // 根据授权类型处理
  59. $response = match ($grantType) {
  60. 'client_credentials' => $this->handleClientCredentials(
  61. $validation->app,
  62. $validation->scopes ?? []
  63. ),
  64. 'authorization_code' => $this->handleAuthorizationCode(
  65. $validation->app,
  66. $data['code'],
  67. $validation->scopes ?? []
  68. ),
  69. 'refresh_token' => $this->handleRefreshToken($data['refresh_token']),
  70. default => $this->errorResponse('不支持的授权类型', [], 400)
  71. };
  72. // 记录运行时间
  73. $requestLogger->setRunTime($startTime);
  74. return $response;
  75. } catch (\Exception $e) {
  76. // 记录错误信息和运行时间
  77. $requestLogger->setError($e->getMessage());
  78. $requestLogger->setRunTime($startTime);
  79. return $this->errorResponse('获取令牌失败', ['message' => $e->getMessage()], 500);
  80. }
  81. }
  82. /**
  83. * 处理客户端凭证授权
  84. *
  85. * @param \App\Module\OpenAPI\Models\OpenApiApp $app
  86. * @param array $scopes
  87. * @return JsonResponse
  88. */
  89. protected function handleClientCredentials(\App\Module\OpenAPI\Models\OpenApiApp $app, array $scopes): JsonResponse
  90. {
  91. // 生成访问令牌
  92. $tokenData = $this->authService->generateAccessToken($app, 0, $scopes);
  93. return $this->successResponse('令牌获取成功', $tokenData);
  94. }
  95. /**
  96. * 处理授权码授权
  97. *
  98. * @param \App\Module\OpenAPI\Models\OpenApiApp $app
  99. * @param string $code
  100. * @param array $scopes
  101. * @return JsonResponse
  102. */
  103. protected function handleAuthorizationCode(\App\Module\OpenAPI\Models\OpenApiApp $app, string $code, array $scopes): JsonResponse
  104. {
  105. // 验证授权码
  106. $codeData = $this->authService->validateAuthCode($code, $app->app_id);
  107. if (!$codeData) {
  108. return $this->errorResponse('授权码无效', [], 400);
  109. }
  110. // 生成访问令牌
  111. $tokenData = $this->authService->generateAccessToken(
  112. $app,
  113. $codeData['user_id'],
  114. $scopes
  115. );
  116. return $this->successResponse('令牌获取成功', $tokenData);
  117. }
  118. /**
  119. * 处理刷新令牌
  120. *
  121. * @param string $refreshToken
  122. * @return JsonResponse
  123. */
  124. protected function handleRefreshToken(string $refreshToken): JsonResponse
  125. {
  126. // 刷新访问令牌
  127. $tokenData = $this->authService->refreshAccessToken($refreshToken);
  128. if (!$tokenData) {
  129. return $this->errorResponse('刷新令牌无效', [], 400);
  130. }
  131. return $this->successResponse('令牌刷新成功', $tokenData);
  132. }
  133. /**
  134. * 刷新令牌
  135. *
  136. * @param Request $request
  137. * @return JsonResponse
  138. */
  139. public function refresh(Request $request): JsonResponse
  140. {
  141. $startTime = microtime(true);
  142. // 初始化请求日志记录器
  143. $requestLogger = new \App\Module\System\Services\RequestLogger($request);
  144. $requestLogger->setRouter("openapi/auth/refresh");
  145. try {
  146. $refreshToken = $request->input('refresh_token');
  147. if (!$refreshToken) {
  148. $requestLogger->setError('缺少刷新令牌');
  149. $requestLogger->setRunTime($startTime);
  150. return $this->errorResponse('缺少刷新令牌', [], 400);
  151. }
  152. $tokenData = $this->authService->refreshAccessToken($refreshToken);
  153. if (!$tokenData) {
  154. $requestLogger->setError('刷新令牌无效');
  155. $requestLogger->setRunTime($startTime);
  156. return $this->errorResponse('刷新令牌无效', [], 400);
  157. }
  158. // 记录运行时间
  159. $requestLogger->setRunTime($startTime);
  160. return $this->successResponse('令牌刷新成功', $tokenData);
  161. } catch (\Exception $e) {
  162. // 记录错误信息和运行时间
  163. $requestLogger->setError($e->getMessage());
  164. $requestLogger->setRunTime($startTime);
  165. return $this->errorResponse('刷新令牌失败', ['message' => $e->getMessage()], 500);
  166. }
  167. }
  168. /**
  169. * 撤销令牌
  170. *
  171. * @param Request $request
  172. * @return JsonResponse
  173. */
  174. public function revoke(Request $request): JsonResponse
  175. {
  176. try {
  177. $token = $request->input('token');
  178. if (!$token) {
  179. return $this->errorResponse('缺少令牌', [], 400);
  180. }
  181. // 这里可以实现令牌撤销逻辑
  182. // 暂时返回成功响应
  183. return $this->successResponse('令牌已撤销');
  184. } catch (\Exception $e) {
  185. return $this->errorResponse('撤销令牌失败', ['message' => $e->getMessage()], 500);
  186. }
  187. }
  188. /**
  189. * 生成JWT令牌
  190. *
  191. * @param Request $request
  192. * @return JsonResponse
  193. */
  194. public function jwt(Request $request): JsonResponse
  195. {
  196. $startTime = microtime(true);
  197. // 初始化请求日志记录器
  198. $requestLogger = new \App\Module\System\Services\RequestLogger($request);
  199. $requestLogger->setRouter("openapi/auth/jwt");
  200. try {
  201. $appId = $request->input('app_id');
  202. $appSecret = $request->input('app_secret');
  203. // 验证应用
  204. $app = $this->openApiService->validateApp($appId, $appSecret);
  205. if (!$app) {
  206. $requestLogger->setError('应用认证失败');
  207. $requestLogger->setRunTime($startTime);
  208. return $this->errorResponse('应用认证失败', [], 401);
  209. }
  210. // 生成JWT令牌
  211. $payload = [
  212. 'user_id' => $request->input('user_id', 0),
  213. 'scopes' => $app->scopes,
  214. ];
  215. $token = $this->authService->generateJwtToken($app, $payload);
  216. // 记录运行时间
  217. $requestLogger->setRunTime($startTime);
  218. return $this->successResponse('JWT令牌生成成功', [
  219. 'token' => $token,
  220. 'token_type' => 'Bearer',
  221. 'expires_in' => config('openapi.auth.jwt.expire', 3600),
  222. ]);
  223. } catch (\Exception $e) {
  224. // 记录错误信息和运行时间
  225. $requestLogger->setError($e->getMessage());
  226. $requestLogger->setRunTime($startTime);
  227. return $this->errorResponse('生成JWT令牌失败', ['message' => $e->getMessage()], 500);
  228. }
  229. }
  230. /**
  231. * 验证JWT令牌
  232. *
  233. * @param Request $request
  234. * @return JsonResponse
  235. */
  236. public function verifyJwt(Request $request): JsonResponse
  237. {
  238. try {
  239. $token = $request->input('token');
  240. if (!$token) {
  241. return $this->errorResponse('缺少令牌', [], 400);
  242. }
  243. $payload = $this->authService->validateJwtToken($token);
  244. if (!$payload) {
  245. return $this->errorResponse('令牌无效', [], 401);
  246. }
  247. return $this->successResponse('令牌验证成功', $payload);
  248. } catch (\Exception $e) {
  249. return $this->errorResponse('验证令牌失败', ['message' => $e->getMessage()], 500);
  250. }
  251. }
  252. /**
  253. * 返回成功响应
  254. *
  255. * @param string $message
  256. * @param array $data
  257. * @return JsonResponse
  258. */
  259. protected function successResponse(string $message, array $data = []): JsonResponse
  260. {
  261. return response()->json([
  262. 'success' => true,
  263. 'message' => $message,
  264. 'data' => $data,
  265. 'timestamp' => time(),
  266. ]);
  267. }
  268. /**
  269. * 返回错误响应
  270. *
  271. * @param string $message
  272. * @param array $errors
  273. * @param int $code
  274. * @return JsonResponse
  275. */
  276. protected function errorResponse(string $message, array $errors = [], int $code = 400): JsonResponse
  277. {
  278. return response()->json([
  279. 'success' => false,
  280. 'message' => $message,
  281. 'errors' => $errors,
  282. 'timestamp' => time(),
  283. ], $code);
  284. }
  285. }