clientAuthService->authenticateConfidentialClient($request); $grantType = trim((string) $request->input('grant_type', '')); $responseData = match ($grantType) { 'authorization_code' => $this->handleAuthorizationCodeGrant($request, $client), 'refresh_token' => $this->handleRefreshTokenGrant($request, $client), default => throw new OAuthProtocolException('unsupported_grant_type', 'Unsupported grant_type.'), }; return response() ->json($responseData) ->header('Cache-Control', 'no-store') ->header('Pragma', 'no-cache'); } catch (OAuthProtocolException $exception) { $response = response() ->json($exception->toResponsePayload(), $exception->httpStatus) ->header('Cache-Control', 'no-store') ->header('Pragma', 'no-cache'); if ($exception->oauthError === 'invalid_client') { $response->header('WWW-Authenticate', 'Basic realm="OAuth"'); } return $response; } } #[Apidoc\Title('OAuth Revoke'), Apidoc\Method('POST'), Apidoc\Url('/oauth/revoke')] public function revoke(Request $request): JsonResponse { try { $client = $this->clientAuthService->authenticateConfidentialClient($request); $validator = Validator::make($request->all(), [ 'token' => ['required', 'string'], 'token_type_hint' => ['nullable', 'string'], ]); if ($validator->fails()) { throw new OAuthProtocolException('invalid_request', (string) $validator->errors()->first()); } $this->tokenService->revokeTokenForClient($client, trim((string) $request->input('token'))); return response()->json([], 200); } catch (OAuthProtocolException $exception) { $response = response()->json($exception->toResponsePayload(), $exception->httpStatus); if ($exception->oauthError === 'invalid_client') { $response->header('WWW-Authenticate', 'Basic realm="OAuth"'); } return $response; } } /** * @return array */ private function handleAuthorizationCodeGrant(Request $request, OauthClient $client): array { $validator = Validator::make($request->all(), [ 'code' => ['required', 'string'], 'redirect_uri' => ['required', 'url:http,https'], ]); if ($validator->fails()) { throw new OAuthProtocolException('invalid_request', (string) $validator->errors()->first()); } $redirectUri = (string) $request->input('redirect_uri'); if (! $this->clientAuthService->isRedirectUriAllowed($client, $redirectUri)) { throw new OAuthProtocolException('invalid_grant', 'redirect_uri mismatch.'); } return $this->tokenService->exchangeAuthorizationCode( client: $client, code: trim((string) $request->input('code')), redirectUri: $redirectUri ); } /** * @return array */ private function handleRefreshTokenGrant(Request $request, OauthClient $client): array { $validator = Validator::make($request->all(), [ 'refresh_token' => ['required', 'string'], ]); if ($validator->fails()) { throw new OAuthProtocolException('invalid_request', (string) $validator->errors()->first()); } return $this->tokenService->exchangeRefreshToken( client: $client, refreshToken: trim((string) $request->input('refresh_token')) ); } }