webman_ad/app/controller/OAuthController.php
2025-02-22 18:56:53 +08:00

353 lines
15 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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'];
$listAccessibleCustomers = $this->googleAdsAccountService->runListAccessibleCustomers($option);
if (empty($listAccessibleCustomers)) {
$googleOAuthService = new GoogleOAuthService();
$googleOAuthService->revokeToken($tokens['refresh_token'], $merchantId);
return $this->errorResponse(300, 'has not any google ads account');
}
// $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
]);
}
}