358 lines
15 KiB
PHP
358 lines
15 KiB
PHP
<?php
|
||
|
||
namespace app\controller;
|
||
|
||
use app\service\GoogleOAuthService;
|
||
use app\service\BpsAdAccountService;
|
||
use app\service\GoogleAdsAccountService;
|
||
use support\Request;
|
||
use support\Response;
|
||
use DI\Annotation\Inject;
|
||
use app\model\ThirdUserAdvertiser;
|
||
use app\model\BpsAdsMerchantRelation;
|
||
use app\model\ThirdUser;
|
||
use support\Redis;
|
||
|
||
use app\event\GoogleAdsCustomers;
|
||
use Webman\Event\Event;
|
||
|
||
class OAuthController
|
||
{
|
||
|
||
// 育才定义 绑定广告账号时的该uuid的广告token Redis 键名前缀
|
||
const REDIS_KEY_PREFIX = 'bps-goui:third:token:key:';
|
||
|
||
/**
|
||
* @Inject
|
||
* @var GoogleOAuthService
|
||
*/
|
||
private $googleOAuthService;
|
||
/**
|
||
* @Inject
|
||
* @var BpsAdAccountService
|
||
*/
|
||
private $bpsAdAccountService;
|
||
|
||
/**
|
||
* @Inject
|
||
* @var GoogleAdsAccountService
|
||
*/
|
||
private $googleAdsAccountService;
|
||
|
||
|
||
public function getAuthCode(Request $request)
|
||
{
|
||
$state = $request->get('state') ?? $request->jwtClaims['merchant_id'];
|
||
$authUrl = $this->googleOAuthService->getAuthUrl($state);
|
||
return $this->successResponse([
|
||
'url' => $authUrl,
|
||
], $request);
|
||
}
|
||
|
||
//废弃2025-2-13
|
||
public function listThirdUserInfos(Request $request)
|
||
{
|
||
$options = $request->all();
|
||
$options['jwtClaims'] = $request->jwtClaims;
|
||
|
||
$authorizedThirdUsers =
|
||
[
|
||
'facebook' => ['status' => 0],
|
||
'google' => ['status' => 0],
|
||
'tiktok' => ['status' => 0],
|
||
];
|
||
// $accounts = $this->bpsAdAccountService->getAllThirdUsers(['uid' => $options['jwtClaims']['uid']]);
|
||
$accounts = $this->bpsAdAccountService->getAllThirdUsers(['merchant_id' => $options['jwtClaims']['merchant_id']]);
|
||
|
||
foreach ($accounts as $account) {
|
||
$authorizedThirdUsers[$account['third_type']] = [
|
||
'status' => 1,
|
||
'id' => $account['id'],
|
||
];
|
||
}
|
||
// 返回结果
|
||
return $this->successResponse($authorizedThirdUsers, $request);
|
||
|
||
}
|
||
|
||
public function handleCallback(Request $request)
|
||
{
|
||
// $state = $request->input('state') ?? $request->jwtClaims['uid'];
|
||
$state = $request->input('state') ?? $request->jwtClaims['merchant_id'];
|
||
$merchantId = $request->jwtClaims['merchant_id'];
|
||
$userId = $request->jwtClaims['uid'];
|
||
$code = $request->input('code'); // 授权码
|
||
|
||
if (!$state) {
|
||
return $this->errorResponse(300, 'Invalid state parameter');
|
||
}
|
||
// state值验证通过,继续处理授权码
|
||
$googleOAuthService = new GoogleOAuthService();
|
||
|
||
$tokens = $googleOAuthService->getRefreshToken($code);
|
||
|
||
// $tokens = [
|
||
// 'access_token' => 'ya29.a0AXeO80QFiuV13I4ZCB4I8NQBVI2rnJsHlyBluSbbe0AUtqK3GDTeg50ktAXsqbG6YiY4paIqdlkTJgzzQZ0qZj1Nwz4wcx91XALOAtjJQC28xIruDc2ngt5a64IETQ_-ItbWdHW75tIUVcfKv7uaYYMSYs6juTJZ8zzLcy_2aCgYKAVgSARMSFQHGX2Mi2SLHpao46UhAg0Gy6LXLkg0175',
|
||
// 'refresh_token' => '1//0gZUuWDXHT45KCgYIARAAGBASNwF-L9IrRsKsk2dWR0jVvwji_pmDBtyvjbl1KCJ-btzLcfy4q4cRYvFebFmtqMDZAv1vdtbY470',
|
||
// 'id_token' => 'eyJhbGciOiJSUzI1NiIsImtpZCI6IjVkMTJhYjc4MmNiNjA5NjI4NWY2OWU0OGFlYTk5MDc5YmI1OWNiODYiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJhenAiOiI4MTIxNzg3ODI5MTMtaTNkZTBodDN0Ymw1azBrNDhhbG1qams3MXE3bjhiNW4uYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJhdWQiOiI4MTIxNzg3ODI5MTMtaTNkZTBodDN0Ymw1azBrNDhhbG1qams3MXE3bjhiNW4uYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJzdWIiOiIxMTc3MjM1MDcwMTEyNTkyMjM2MDUiLCJlbWFpbCI6Ijc3NjY4OEBnbWFpbC5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiYXRfaGFzaCI6InhscUhkazR2OW9WdHpYUGZJUkpONGciLCJuYW1lIjoiTGVvIiwicGljdHVyZSI6Imh0dHBzOi8vbGgzLmdvb2dsZXVzZXJjb250ZW50LmNvbS9hL0FDZzhvY0tIYjJCdTVFQVhkQ2lvdl8tYmg4ZWNvc1VaMHlELTVYbHZfUUdXSHJzbVF4aGx1dz1zOTYtYyIsImdpdmVuX25hbWUiOiJMZW8iLCJpYXQiOjE3Mzk3ODMwMDcsImV4cCI6MTczOTc4NjYwN30.IxsMOMF4aHvSn7Ug65PcGnK3X5nnRKzshcHgwGT5RCC9lcCnXmAaXMjjQWOtXOFcrRMCPG-HM3SmaCsrC-ThzvUoCzXl6ArQkZxpS3JA5b-KdmWK8KxnK9Lr63G9xvbr56ys_RIPXNyNuzlmY1Xzc3Pr920fJl43haJDp3HOx9DlRYQctC53mw6t6DoqfhCKItZ7jON65JWG4CJhqxZiFJNW7RaKAKzUncVoen_D1SphLlOMda0m6YBgj8UDcyo5U0X7dZM7f_oMMjHkuS252XG9mJ2QH74K-7tlO0GPUEWuUkprvFSay5LU5TzJIJCM9EkoD4hvyYB24oCHgqUiHA',
|
||
//
|
||
// ];
|
||
|
||
if (!isset($tokens['refresh_token'])) {
|
||
if (isset($tokens['access_token'])) {
|
||
return $this->errorResponse(300, 'Google Ads Account is Authorized');
|
||
}
|
||
return $this->errorResponse(300, 'Refresh Token getting failed');
|
||
} else {
|
||
//如果这个授权用户名下没有任何广告账号
|
||
$option = [];
|
||
$option['refresh_token'] = $tokens['refresh_token'];
|
||
try {
|
||
$listAccessibleCustomers = $this->googleAdsAccountService->runListAccessibleCustomers($option);
|
||
}catch (\Exception $e) {
|
||
$googleOAuthService = new GoogleOAuthService();
|
||
$googleOAuthService->revokeToken($tokens['refresh_token'], $merchantId);
|
||
return $this->errorResponse(300, 'The Google account not associated with any Ads accounts');
|
||
}
|
||
if (empty($listAccessibleCustomers)) {
|
||
$googleOAuthService = new GoogleOAuthService();
|
||
$googleOAuthService->revokeToken($tokens['refresh_token'], $merchantId);
|
||
|
||
return $this->errorResponse(300, 'The Google account not associated with any active Ads accounts');
|
||
}
|
||
|
||
// $googleOAuthService->saveRefreshToken($tokens['refresh_token'], $state); //作废2025-2-13
|
||
$googleOAuthService->saveRefreshTokenNew($tokens['refresh_token'], $tokens['access_token'], $merchantId, $userId);
|
||
|
||
// 生成 UUID
|
||
$uuid = $this->generateUuid();
|
||
// echo $uuid; // 例如:f47ac10b-58cc-4372-a567-0e02b2c3d479
|
||
$redisKey = self::REDIS_KEY_PREFIX . $uuid;
|
||
//把$tokens['refresh_token']存入redis的redisKey, 并设置过期时间为10分钟
|
||
Redis::setex($redisKey, 600, $tokens['refresh_token']);
|
||
// 保存refresh token到数据库
|
||
// $googleOAuthService->saveRefreshToken($tokens['refresh_token'], $state, $uuid);
|
||
// // 触发事件
|
||
return $this->successResponse(['token' => $uuid], $request);
|
||
}
|
||
// return $this->successResponse($tokens, $request);
|
||
|
||
}
|
||
|
||
//另一种方案,暂时没用
|
||
public function handleCallbackNew(Request $request)
|
||
{
|
||
// $state = $request->input('state') ?? $request->jwtClaims['uid'];
|
||
$state = $request->input('state') ?? $request->jwtClaims['merchant_id'];
|
||
$code = $request->input('code'); // 授权码
|
||
|
||
if (!$state) {
|
||
return $this->errorResponse(300, 'Invalid state parameter');
|
||
}
|
||
// state值验证通过,继续处理授权码
|
||
$googleOAuthService = new GoogleOAuthService();
|
||
|
||
$tokens = $googleOAuthService->getRefreshToken($code);
|
||
|
||
if (!isset($tokens['refresh_token'])) {
|
||
if (isset($tokens['access_token'])) {
|
||
return $this->errorResponse(300, 'Google Ads Account is Authorized');
|
||
}
|
||
return $this->errorResponse(300, 'Refresh Token getting failed');
|
||
}
|
||
|
||
// 生成 UUID
|
||
$uuid = $this->generateUuid();
|
||
// echo $uuid; // 例如:f47ac10b-58cc-4372-a567-0e02b2c3d479
|
||
$redisKey = self::REDIS_KEY_PREFIX . $uuid;
|
||
//把$tokens['refresh_token']存入redis的redisKey, 并设置过期时间为10分钟
|
||
Redis::setex($redisKey, 600, $tokens['refresh_token']);
|
||
// 保存refresh token到数据库
|
||
// $googleOAuthService->saveRefreshToken($tokens['refresh_token'], $state, $uuid);
|
||
// // 触发事件
|
||
return $this->successResponse(['token' => $uuid], $request);
|
||
|
||
}
|
||
|
||
public function generateUuid()
|
||
{
|
||
$data = random_bytes(16);
|
||
$data[6] = chr(ord($data[6]) & 0x0f | 0x40); // 设置版本为 4
|
||
$data[8] = chr(ord($data[8]) & 0x3f | 0x80); // 设置变体为 RFC 4122
|
||
return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
|
||
}
|
||
|
||
|
||
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, $request);
|
||
}
|
||
// 保存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], $request);
|
||
}
|
||
|
||
public function revokeRefreshToken(Request $request)
|
||
{
|
||
// $accessToken = $request->input('token'); //access token
|
||
// $customerId = isset($requestData['customer_id']) ? $requestData['customer_id'] : getenv('GOOGLE_ADS_CUSTOMER_ID');
|
||
// $customerId = getenv('GOOGLE_ADS_CUSTOMER_ID'); //临时指定
|
||
|
||
$merchant_id = $request->input('merchant_id') ?? $request->jwtClaims['merchant_id'];
|
||
|
||
// 通过 advertiser_id 查询 ThirdUserAdvertiser,联表查询 ThirdUser 数据
|
||
$thirdUser = BpsAdsMerchantRelation::where('merchant_id', $merchant_id)->where('platform', 2)->find(); // 获取第一个结果
|
||
// dump($thirdUser); return ($uid);
|
||
if (!$thirdUser) {
|
||
return $this->errorResponse(300, '未授权');
|
||
}
|
||
$accessToken = $thirdUser->access_token;
|
||
// dump($accessToken);
|
||
// return ($merchant_id);
|
||
|
||
$googleOAuthService = new GoogleOAuthService();
|
||
$googleOAuthService->revokeToken($accessToken, $merchant_id);
|
||
return $this->successResponse(['deleted' => 'success'], $request);
|
||
|
||
}
|
||
|
||
|
||
//保存某个主体的全部access广告账号
|
||
public function saveAdvertisers(Request $request)
|
||
{
|
||
// $customerIds = $request->input('third_user_list_customers'); // customer_id_list每个元素包含advertiser_id
|
||
|
||
|
||
// $thirdUserId = $request->input('third_user_id'); // bps_third_user的id
|
||
// $googleOAuthService = new GoogleOAuthService();
|
||
// $hasThirdUser = $googleOAuthService->bindThirdUserAdvertiser($customerId, $thirdUserId);
|
||
// if (!$hasThirdUser) {
|
||
// return $this->errorResponse(300, 'Invalid state parameter');
|
||
// }
|
||
// return $this->successResponse($hasThirdUser);
|
||
}
|
||
|
||
|
||
public function testRefreshToken(Request $request)
|
||
{
|
||
$options = $request->all();
|
||
// dump($options);
|
||
return $this->googleOAuthService->queue($options);
|
||
|
||
// return $this->successResponse([],$request);
|
||
|
||
//发布事件
|
||
// $dayBeforeYesterdayStart = date('Y-m-d', strtotime('-2 day'));
|
||
// dump($dayBeforeYesterdayStart . '更新' . GoogleAdsDateDatas::type . '开始');
|
||
// Event::emit(GoogleAdsDateDatas::type, ['date' => $dayBeforeYesterdayStart]);
|
||
|
||
// dump(date('Y-m-d H:i:s') . '更新' . GoogleAdsCampaigns::type . '开始');
|
||
// Event::emit(GoogleAdsCampaigns::type, []);
|
||
// dump(date('Y-m-d H:i:s') . '更新' . GoogleAdsGroups::type . '开始');
|
||
// Event::emit(GoogleAdsGroups::type, []);
|
||
// dump(date('Y-m-d H:i:s') . '更新' . GoogleAdsAds::type . '开始');
|
||
// Event::emit(GoogleAdsAdMaterials::type, []);
|
||
// dump(date('Y-m-d H:i:s') . '更新' . GoogleAdsMaterials::type . '开始');
|
||
// Event::emit(GoogleAdsMaterials::type, []);
|
||
|
||
// return $this->successResponse(['data' => []]);
|
||
|
||
|
||
// $customers = $this->googleOAuthService->getGoogleAdCustomers([]);
|
||
// return $this->successResponse(['data' => $customers]);
|
||
|
||
|
||
// $list = ThinkDb::table('bps.bps_third_user')->where('third_type', 'google')->select();
|
||
// return $this->successResponse($list);
|
||
|
||
// $user = new ThirdUserModel;
|
||
// $data = [
|
||
// ['access_token' => 'bar', 'third_type' => 'google'],
|
||
// ['access_token' => 'bar1', 'third_type' => 'google'],
|
||
// ['access_token' => 'bar2', 'third_type' => 'google']
|
||
// ];
|
||
// $user->saveAll($data);
|
||
|
||
//
|
||
//
|
||
// ThinkDb::table('bps.bps_third_user')->insertAll($data);
|
||
|
||
// ThinkDb::name('bps_third_user')
|
||
// ->update(['id' => 10, 'user_id' => 'bbb']);
|
||
//
|
||
// return $this->successResponse(['added' =>'success']);
|
||
|
||
// 使用 ThinkDb 进行联表查询
|
||
// $advertiserId = 'your-advertiser-id'; // 假设你已经获得了广告商ID
|
||
// $requestData = $request->all(); // 获取请求数据
|
||
// $customerId = $requestData['customer_id'];
|
||
//
|
||
// // 通过 advertiser_id 查询 ThirdUserAdvertiser,联表查询 ThirdUser 数据
|
||
// $userAdvertiser = ThirdUserAdvertiser::with('googleUser') // 联表查询 user 关联
|
||
// ->where('advertiser_id', $customerId) // 根据 advertiser_id 查询
|
||
// ->find(); // 获取第一个结果
|
||
|
||
// 如果找到广告主数据
|
||
// if ($userAdvertiser && $userAdvertiser->googleUser) {
|
||
// // 获取关联用户的 access_token
|
||
// $accessToken = $userAdvertiser->googleUser->access_token;
|
||
//// dump($accessToken); // 打印 access_token
|
||
// return $this->successResponse($accessToken); // 返回 access_token
|
||
// } else {
|
||
// // 如果没有找到广告主或关联的用户,返回错误信息
|
||
//// dump('未找到该广告主或关联的用户');
|
||
// return $this->errorResponse('101', '未找到该广告主或关联的用户');
|
||
// }
|
||
|
||
}
|
||
|
||
|
||
// 可以加入一些公共方法
|
||
protected function successResponse($data, Request $request): Response
|
||
{
|
||
if ($request->jwtNewToken) {
|
||
return new Response(200,
|
||
[
|
||
'Content-Type' => 'application/json',
|
||
'X-New-Token' => $request->jwtNewToken
|
||
],
|
||
json_encode($data, JSON_UNESCAPED_UNICODE));
|
||
} else {
|
||
return Json([
|
||
'code' => 0,
|
||
'msg' => 'ok',
|
||
'data' => $data,
|
||
]);
|
||
}
|
||
}
|
||
|
||
protected function errorResponse($code, $message, $data = []): Response
|
||
{
|
||
return Json([
|
||
'code' => $code,
|
||
'msg' => $message ?: 'error',
|
||
'data' => $data
|
||
]);
|
||
}
|
||
|
||
} |