diff --git a/app/controller/AdController.php b/app/controller/AdController.php index f1bdd01..a037e28 100644 --- a/app/controller/AdController.php +++ b/app/controller/AdController.php @@ -87,7 +87,7 @@ class AdController { return Json([ 'code' => 0, - 'msg' => date('Y-m-d'), + 'msg' => 'ok', 'data' => $data, ]); } diff --git a/app/controller/OAuthController.php b/app/controller/OAuthController.php new file mode 100644 index 0000000..674eaae --- /dev/null +++ b/app/controller/OAuthController.php @@ -0,0 +1,105 @@ +googleOAuthService->getAuthUrl(); + return $this->successResponse([ + 'url' => $authUrl, + ]); + } + + + public function handleCallback(Request $request) + { +// $state = $request->input('state'); // 从Google回调中获取state + $code = $request->input('code'); // 授权码 + + // 验证state值是否与保存的值一致 +// if ($state !== $_SESSION['oauth_state']) { +// if ($state !== '7a7a9edad5b48c127b7c14fabe39fae0') { +// return $this->errorResponse(400, 'Invalid state parameter'); +// } + // state值验证通过,继续处理授权码 + $googleOAuthService = new GoogleOAuthService(); + $tokens = $googleOAuthService->getRefreshToken($code); + + return $this->successResponse($tokens); + } + + public function getRefreshToken(Request $request) + { + $authCode = $request->input('code'); +// $state = $request->input('state'); // 从Google回调中获取state + // 验证state值是否与保存的值一致 +// if ($state !== $_SESSION['oauth_state']) { +// return $this->errorResponse(400, 'Invalid state parameter'); +// } + $googleOAuthService = new GoogleOAuthService(); + + $tokens = $googleOAuthService->getRefreshToken($authCode); + if (!isset($tokens['refresh_token'])) { + return $this->successResponse($tokens); + } + // 保存refresh token到数据库 +// $googleOAuthService->saveRefreshToken($tokens['refresh_token'], $tokens['access_token'], $request->user_id); + $googleOAuthService->saveRefreshToken($tokens['refresh_token'], $tokens['access_token']); + return $this->successResponse($tokens); + } + + public function useRefreshToken(Request $request) + { + $refreshToken = $request->input('refresh_token'); + $googleOAuthService = new GoogleOAuthService(); + + $newAccessToken = $googleOAuthService->useRefreshToken($refreshToken); + return $this->successResponse(['access_token' => $newAccessToken]); + } + + public function revokeRefreshToken(Request $request) + { + $accessToken = $request->input('token'); //access token + $googleOAuthService = new GoogleOAuthService(); + + $googleOAuthService->revokeToken($accessToken); + return $this->successResponse(['deleted' => 'success']); + + } + + + // 可以加入一些公共方法 + protected function successResponse($data): Response + { + return Json([ + 'code' => 0, + 'msg' => 'ok', + 'data' => $data, + ]); + } + + protected function errorResponse($code, $message, $data = []): Response + { + return Json([ + 'code' => $code, + 'msg' => $message ?: 'error', + 'data' => $data + ]); + } + +} \ No newline at end of file diff --git a/app/model/ThirdUser.php b/app/model/ThirdUser.php new file mode 100644 index 0000000..e019ba1 --- /dev/null +++ b/app/model/ThirdUser.php @@ -0,0 +1,10 @@ +post('https://oauth2.googleapis.com/token', [ + 'form_params' => [ + 'code' => $authCode, + 'client_id' => getenv('GOOGLE_CLIENT_ID'), + 'client_secret' => getenv('GOOGLE_CLIENT_SECRET'), + 'redirect_uri' => getenv('GOOGLE_REDIRECT_URI'), + 'grant_type' => 'authorization_code', + ], + ]); + + return json_decode($response->getBody(), true); + } + + public function saveRefreshToken($refreshToken, $accessToken) + { + // 使用ThinkORM保存数据到bps_third_user表 +// $thirdUser = new \App\Models\ThirdUser(); +// $thirdUser->access_token = $accessToken; +// $thirdUser->is_default = true; +// $thirdUser->random_code = bin2hex(random_bytes(16)); // 生成随机码 +// $thirdUser->third_type = 'google'; +// $thirdUser->user_id = $userId; +// $thirdUser->save(); + $data = [ + 'access_token' => $refreshToken, + 'is_default' => 't', + 'third_type' => 'google', + ]; + $tableName = 'bps_third_user'; + $tableName = getenv('DB_PG_SCHEMA') ? getenv('DB_PG_SCHEMA') . '.' . $tableName : 'public' . $tableName; + + $sql = " + INSERT INTO {$tableName} + (access_token, is_default, third_type) + VALUES (:access_token, :is_default, :third_type) + ON CONFLICT (user_id) + DO UPDATE SET + access_token = EXCLUDED.access_token, + is_default = EXCLUDED.is_default, + "; +// $sql = " +// INSERT INTO {$tableName} +// (access_token, is_default, random_code, third_type, user_id, facebook_user_id) +// VALUES (:access_token, :is_default, :random_code, :third_type, :user_id, :facebook_user_id) +// ON CONFLICT (user_id) +// DO UPDATE SET +// access_token = EXCLUDED.access_token, +// is_default = EXCLUDED.is_default, +// random_code = EXCLUDED.random_code, +// third_type = EXCLUDED.third_type, +// "; + + ThinkDb::execute($sql, $data); + } + + + public function revokeToken($accessToken) + { + $client = new Client(); + $client->post('https://oauth2.googleapis.com/revoke', [ + 'form_params' => [ + 'token' => $accessToken, + ], + ]); + + // 在数据库中删除或标记该`refresh_token`为无效 +// \App\Models\ThirdUser::where('access_token', $refreshToken)->delete(); + } + + public function useRefreshToken($refreshToken) + { + $client = new Client(); + $response = $client->post('https://oauth2.googleapis.com/token', [ + 'form_params' => [ + 'refresh_token' => $refreshToken, + 'client_id' => getenv('GOOGLE_CLIENT_ID'), + 'client_secret' => getenv('GOOGLE_CLIENT_SECRET'), + 'grant_type' => 'refresh_token', + ], + ]); + + $data = json_decode($response->getBody(), true); + return $data['access_token']; + } + + +} \ No newline at end of file diff --git a/config/route.php b/config/route.php index 0af3a3a..4c99621 100644 --- a/config/route.php +++ b/config/route.php @@ -14,6 +14,7 @@ //use app\controller\IndexController; use app\controller\AdController; +use app\controller\OAuthController; use app\controller\GoogleAdsController; use Webman\Route; @@ -48,6 +49,14 @@ Route::group('/googleads', function () { Route::group('/adgroup', function () { Route::post('/export', [AdController::class, 'exportGroupsToExcel']); }); + + Route::group('/auth', function () { + Route::get('/code', [OAuthController::class, 'getAuthCode']); + Route::post('/callback', [OAuthController::class, 'handleCallback']); + Route::post('/refresh_token_get', [OAuthController::class, 'getRefreshToken']); + Route::post('/refresh_token_use', [OAuthController::class, 'useRefreshToken']); + Route::post('/refresh_token_revoke', [OAuthController::class, 'revokeRefreshToken']); + }); }); Route::group('/campaign', function () {