| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- <?php
- namespace App\Module\OAuth\Controllers;
- use App\Http\Controllers\Controller;
- use App\Module\OAuth\Services\OAuth;
- use App\Module\User\Models\User;
- use Illuminate\Http\Request;
- use Illuminate\Http\JsonResponse;
- use Illuminate\Support\Facades\Hash;
- class TokenController extends Controller
- {
- /**
- * 令牌端点
- */
- public function token(Request $request): JsonResponse
- {
- // 验证请求参数
- $request->validate([
- 'grant_type' => 'required|in:authorization_code,password,client_credentials,refresh_token',
- 'client_id' => 'required|string',
- 'client_secret' => 'required|string',
- ]);
- // 验证客户端
- if (!OAuth::validateClient($request->client_id, $request->client_secret, $request->grant_type)) {
- return response()->json([
- 'error' => 'invalid_client',
- 'error_description' => '无效的客户端凭证'
- ], 401);
- }
- // 根据授权类型处理
- switch ($request->grant_type) {
- case 'authorization_code':
- return $this->handleAuthorizationCode($request);
- case 'password':
- return $this->handlePassword($request);
- case 'client_credentials':
- return $this->handleClientCredentials($request);
- case 'refresh_token':
- return $this->handleRefreshToken($request);
- }
- }
- /**
- * 处理授权码模式
- */
- protected function handleAuthorizationCode(Request $request): JsonResponse
- {
- $request->validate([
- 'code' => 'required|string',
- 'redirect_uri' => 'required|url'
- ]);
- // 获取并验证授权码
- $codeKey = 'oauth_auth_code:' . $request->code;
- $codeData = cache()->get($codeKey);
- if (!$codeData) {
- return response()->json([
- 'error' => 'invalid_grant',
- 'error_description' => '无效的授权码'
- ], 400);
- }
- // 验证客户端ID和回调地址
- if ($codeData['client_id'] !== $request->client_id ||
- $codeData['redirect_uri'] !== $request->redirect_uri) {
- return response()->json([
- 'error' => 'invalid_grant',
- 'error_description' => '授权码验证失败'
- ], 400);
- }
- // 删除使用过的授权码
- cache()->delete($codeKey);
- // 创建访问令牌
- $token = OAuth::createAccessToken(
- $request->client_id,
- $codeData['user_id'],
- $codeData['scope'] ? explode(' ', $codeData['scope']) : []
- );
- return $this->tokenResponse($token);
- }
- /**
- * 处理密码模式
- */
- protected function handlePassword(Request $request): JsonResponse
- {
- $request->validate([
- 'username' => 'required|string',
- 'password' => 'required|string',
- 'scope' => 'nullable|string'
- ]);
- // 验证用户凭证
- $user = User::query()->where('email', $request->username)->first();
- if (!$user || !Hash::check($request->password, $user->password)) {
- return response()->json([
- 'error' => 'invalid_grant',
- 'error_description' => '无效的用户凭证'
- ], 400);
- }
- // 创建访问令牌
- $token = OAuth::createAccessToken(
- $request->client_id,
- $user->id,
- $request->scope ? explode(' ', $request->scope) : []
- );
- return $this->tokenResponse($token);
- }
- /**
- * 处理客户端模式
- */
- protected function handleClientCredentials(Request $request): JsonResponse
- {
- $request->validate([
- 'scope' => 'nullable|string'
- ]);
- // 创建访问令牌(不关联用户)
- $token = OAuth::createAccessToken(
- $request->client_id,
- null,
- $request->scope ? explode(' ', $request->scope) : []
- );
- return $this->tokenResponse($token);
- }
- /**
- * 处理刷新令牌
- */
- protected function handleRefreshToken(Request $request): JsonResponse
- {
- $request->validate([
- 'refresh_token' => 'required|string'
- ]);
- // TODO: 实现刷新令牌逻辑
- return response()->json([
- 'error' => 'unsupported_grant_type',
- 'error_description' => '暂不支持刷新令牌'
- ], 400);
- }
- /**
- * 格式化令牌响应
- */
- protected function tokenResponse($token): JsonResponse
- {
- return response()->json([
- 'access_token' => $token->access_token,
- 'token_type' => 'Bearer',
- 'expires_in' => $token->expires_at->diffInSeconds(now()),
- 'scope' => implode(' ', $token->scope ?? []),
- ]);
- }
- }
|