AuthorizeController.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. <?php
  2. namespace App\Module\OAuth\Controllers;
  3. use App\Http\Controllers\Controller;
  4. use App\Module\OAuth\Services\OAuth;
  5. use App\Module\OAuth\Services\AuthService;
  6. use Illuminate\Http\Request;
  7. use Illuminate\Http\JsonResponse;
  8. use Illuminate\View\View;
  9. class AuthorizeController extends Controller
  10. {
  11. protected $auth;
  12. public function __construct(AuthService $auth)
  13. {
  14. $this->auth = $auth;
  15. }
  16. /**
  17. * 显示授权页面
  18. */
  19. public function authorize(Request $request)
  20. {
  21. // 验证请求参数
  22. $request->validate([
  23. 'response_type' => 'required|in:code,token',
  24. 'client_id' => 'required|string',
  25. 'redirect_uri' => 'required|url',
  26. 'scope' => 'nullable|string',
  27. 'state' => 'nullable|string',
  28. ]);
  29. // 获取客户端信息
  30. $client = OAuth::getClient($request->client_id);
  31. if (!$client) {
  32. return response()->json([
  33. 'error' => 'invalid_client',
  34. 'error_description' => '无效的客户端'
  35. ], 400);
  36. }
  37. // 验证回调地址
  38. // dd($request->redirect_uri);
  39. if ($client->redirect_uri !== $request->redirect_uri) {
  40. return response()->json([
  41. 'error' => 'invalid_redirect_uri',
  42. 'error_description' => '无效的回调地址'
  43. ], 400);
  44. }
  45. // 如果用户未登录,保存授权请求参数并重定向到登录页面
  46. if (!$this->auth->check()) {
  47. // 保存授权请求参数到session
  48. session(['oauth_authorize_params' => $request->all()]);
  49. return redirect()->route('login');
  50. }
  51. $user = $this->auth->user();
  52. // 显示授权页面
  53. return view('oauth::authorize', [
  54. 'client' => $client,
  55. 'scopes' => $request->scope ? explode(' ', $request->scope) : [],
  56. 'redirect_uri' => $request->redirect_uri,
  57. 'response_type' => $request->response_type,
  58. 'state' => $request->state,
  59. 'scope' => $request->scope,
  60. ]);
  61. }
  62. /**
  63. * 处理授权请求
  64. */
  65. public function approve(Request $request)
  66. {
  67. // 验证请求
  68. $request->validate([
  69. 'client_id' => 'required|string',
  70. 'redirect_uri' => 'required|url',
  71. 'response_type' => 'required|in:code,token',
  72. 'scope' => 'nullable|string',
  73. 'state' => 'nullable|string',
  74. 'approve' => 'required|boolean',
  75. ]);
  76. // 如果用户未登录,保存授权请求参数并重定向到登录页面
  77. if (!$this->auth->check()) {
  78. session(['oauth_authorize_params' => $request->all()]);
  79. return redirect()->route('login');
  80. }
  81. $user = $this->auth->user();
  82. // 如果用户拒绝授权
  83. if (!$request->approve) {
  84. $params = [
  85. 'error' => 'access_denied',
  86. 'error_description' => '用户拒绝授权'
  87. ];
  88. if ($request->state) {
  89. $params['state'] = $request->state;
  90. }
  91. $url= $request->redirect_uri . '?' . http_build_query($params);
  92. }else{
  93. // 根据响应类型处理
  94. if ($request->response_type === 'token') {
  95. // 简化模式,直接返回访问令牌
  96. $token = OAuth::createAccessToken(
  97. $request->client_id,
  98. $user['id'],
  99. $request->scope ? explode(' ', $request->scope) : []
  100. );
  101. $params = [
  102. 'access_token' => $token->access_token,
  103. 'token_type' => 'Bearer',
  104. 'expires_in' => $token->expires_at->diffInSeconds(now()),
  105. 'scope' => implode(' ', $token->scope ?? []),
  106. ];
  107. if ($request->state) {
  108. $params['state'] = $request->state;
  109. }
  110. $url =$request->redirect_uri . '#' . http_build_query($params);
  111. } else {
  112. // 授权码模式,生成授权码
  113. $code = bin2hex(random_bytes(32));
  114. // 存储授权码信息
  115. cache()->put('oauth_auth_code:' . $code, [
  116. 'client_id' => $request->client_id,
  117. 'user_id' => $user['id'],
  118. 'scope' => $request->scope,
  119. 'redirect_uri' => $request->redirect_uri,
  120. ], 600); // 10分钟有效期
  121. $params = ['code' => $code];
  122. if ($request->state) {
  123. $params['state'] = $request->state;
  124. }
  125. $url = $request->redirect_uri . '?' . http_build_query($params);
  126. }
  127. }
  128. return response()->redirectTo($url);
  129. }
  130. }