281 lines
11 KiB
PHP
281 lines
11 KiB
PHP
<?php
|
||
|
||
namespace app\service;
|
||
|
||
use GuzzleHttp\Client;
|
||
use think\facade\Db as ThinkDb;
|
||
use app\model\ThirdUserAdvertiser;
|
||
use app\model\ThirdUser;
|
||
|
||
class GoogleOAuthService
|
||
{
|
||
public function getAuthUrl($state = '')
|
||
{
|
||
$clientId = getenv('GOOGLE_CLIENT_ID');
|
||
$redirectUri = getenv('GOOGLE_REDIRECT_URI');
|
||
$scope = 'https://www.googleapis.com/auth/adwords';
|
||
$responseType = 'code';
|
||
$accessType = 'offline';
|
||
|
||
// $state = 'state_parameter_passthrough_value'; // 可选,保护防止CSRF
|
||
|
||
// 将state保存到会话或数据库中,稍后验证
|
||
// $_SESSION['oauth_state'] = $state; // 使用PHP会话来保存state
|
||
|
||
// $authUrl = "https://accounts.google.com/o/oauth2/v2/auth?client_id=$clientId&redirect_uri=$redirectUri&scope=$scope&response_type=$responseType&state=$state";
|
||
if (!empty($state)) {
|
||
// 生成随机的state参数,防止CSRF攻击
|
||
// $state = bin2hex(random_bytes(16)); // 生成一个随机字符串
|
||
// $this->saveThirdUser($state);
|
||
$authUrl = "https://accounts.google.com/o/oauth2/v2/auth?client_id=$clientId&redirect_uri=$redirectUri&scope=$scope&response_type=$responseType&access_type=$accessType&state=$state";
|
||
} else {
|
||
$authUrl = "https://accounts.google.com/o/oauth2/v2/auth?client_id=$clientId&redirect_uri=$redirectUri&scope=$scope&response_type=$responseType&access_type=$accessType";
|
||
|
||
}
|
||
return $authUrl;
|
||
}
|
||
|
||
public function getThirdUserByRandomCode($state)
|
||
{
|
||
$tableName = 'bps_third_user';
|
||
$tableName = getenv('DB_PG_SCHEMA') ? getenv('DB_PG_SCHEMA') . '.' . $tableName : 'bps' . $tableName;
|
||
$result = ThinkDb::name($tableName)->where('random_code', $state)->find();
|
||
return $result;
|
||
}
|
||
|
||
public function getRefreshToken($authCode)
|
||
{
|
||
$client = new Client();
|
||
$response = $client->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 saveThirdUser($state)
|
||
{
|
||
//发起授权前,新记录到bps_third_user表
|
||
$data = [
|
||
'random_code' => $state,
|
||
'is_default' => 't',
|
||
'third_type' => 'google',
|
||
];
|
||
$tableName = 'bps_third_user';
|
||
$tableName = getenv('DB_PG_SCHEMA') ? getenv('DB_PG_SCHEMA') . '.' . $tableName : 'bps' . $tableName;
|
||
|
||
$sql = " INSERT INTO {$tableName}
|
||
(random_code, is_default, third_type)
|
||
VALUES (:random_code, :is_default, :third_type";
|
||
ThinkDb::execute($sql, $data);
|
||
}
|
||
|
||
public function getCustomerList($third_user_id = 0)
|
||
{
|
||
$tableName = 'bps_third_user_advertiser';
|
||
$tableName = getenv('DB_PG_SCHEMA') ? getenv('DB_PG_SCHEMA') . '.' . $tableName : 'bps' . $tableName;
|
||
|
||
$sql = "SELECT * FROM {$tableName} WHERE doc_ = :third_user_id";
|
||
$data = ['third_user_id' => $third_user_id];
|
||
|
||
return ThinkDb::query($sql, $data);
|
||
}
|
||
|
||
//保存或更新某个主体部广告账号
|
||
public function saveThirdUserAdvertiser($customer_id, $third_user_id,$login_customer_id,$customer_name = '')
|
||
{
|
||
// 确保 customer_id 和 third_user_id 是字符串
|
||
$customer_id = (string) $customer_id;
|
||
$tableName = 'bps_third_user_advertiser';
|
||
$tableName = getenv('DB_PG_SCHEMA') ? getenv('DB_PG_SCHEMA') . '.' . $tableName : 'bps' . $tableName;
|
||
$data = [
|
||
'doc_' => $third_user_id,
|
||
'advertiser_id' => $customer_id,
|
||
'advertiser_name' => $customer_name,
|
||
'google_login_customer_id' => $login_customer_id,
|
||
];
|
||
|
||
$sql = "
|
||
INSERT INTO {$tableName}
|
||
(advertiser_id,advertiser_name, doc_,google_login_customer_id)
|
||
VALUES (:advertiser_id, :advertiser_name,:doc_,:google_login_customer_id)
|
||
ON CONFLICT (advertiser_id,doc_)
|
||
DO UPDATE SET
|
||
advertiser_name = EXCLUDED.advertiser_name,
|
||
google_login_customer_id = EXCLUDED.google_login_customer_id
|
||
";
|
||
// dump($sql,$data);
|
||
ThinkDb::execute($sql, $data);
|
||
}
|
||
|
||
//绑定某个主体的广告账号
|
||
public function bindThirdUserAdvertiser($customer_id, $third_user_id)
|
||
{
|
||
$tableName = 'bps_third_user';
|
||
$tableName = getenv('DB_PG_SCHEMA') ? getenv('DB_PG_SCHEMA') . '.' . $tableName : 'bps' . $tableName;
|
||
$data = [
|
||
'id' => $third_user_id,
|
||
'user_id' => $customer_id,];
|
||
$sql = "
|
||
UPDATE {$tableName}
|
||
SET user_id = :user_id
|
||
WHERE id = :id
|
||
";
|
||
ThinkDb::execute($sql, $data);
|
||
}
|
||
|
||
public function updateThirdUser($state, $refreshToken): void
|
||
{
|
||
$tableName = 'bps_third_user';
|
||
$tableName = getenv('DB_PG_SCHEMA') ? getenv('DB_PG_SCHEMA') . '.' . $tableName : 'bps' . $tableName;
|
||
$data = [
|
||
'access_token' => $refreshToken,
|
||
'random_code' => $state,];
|
||
$sql = "
|
||
UPDATE {$tableName}
|
||
SET access_token = :access_token
|
||
WHERE random_code = :random_code
|
||
";
|
||
ThinkDb::execute($sql, $data);
|
||
}
|
||
|
||
|
||
public function saveRefreshToken($refreshToken, $state = '')
|
||
{
|
||
// 使用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 : 'bps' . $tableName;
|
||
if (!empty($state)) {
|
||
|
||
$thirdUser = ThirdUser::where('user_id', $state)->find(); // 获取第一个结果
|
||
// dump($thirdUser); return ($uid);
|
||
if ($thirdUser) {
|
||
$data['id'] = $thirdUser->id;
|
||
$sql = "
|
||
UPDATE {$tableName}
|
||
SET
|
||
access_token = :access_token,
|
||
is_default = :is_default,
|
||
third_type = :third_type
|
||
WHERE id = :id
|
||
";
|
||
} else {
|
||
$data['user_id'] = $state;
|
||
$sql = "
|
||
INSERT INTO {$tableName}
|
||
(access_token, is_default, third_type, user_id)
|
||
VALUES (:access_token, :is_default, :third_type, :user_id)
|
||
";
|
||
}
|
||
} else {
|
||
$sql = "
|
||
INSERT INTO {$tableName}
|
||
(access_token, is_default, third_type)
|
||
VALUES (:access_token, :is_default, :third_type)
|
||
";
|
||
}
|
||
ThinkDb::execute($sql, $data);
|
||
}
|
||
|
||
public function updateRefreshToken($refreshToken)
|
||
{
|
||
$customer_id = getenv('GOOGLE_ADS_CUSTOMER_ID');
|
||
//暂时update进行绑定
|
||
$tableName = "bps.bps_third_user";
|
||
// $sql = "UPDATE {$tableName} SET access_token = :access_token WHERE random_code = :random_code";
|
||
$sql = "UPDATE {$tableName} SET access_token = :access_token WHERE user_id = :user_id";
|
||
$data = [
|
||
'access_token' => $refreshToken, // 这里的 $accessToken 是您想要匹配的值
|
||
'user_id' => $customer_id, // 这里的 $accessToken 是您想要匹配的值
|
||
];
|
||
// 执行 SQL 语句
|
||
$result = ThinkDb::execute($sql, $data);
|
||
}
|
||
|
||
|
||
public function revokeToken($accessToken, $third_user_id)
|
||
{
|
||
$client = new Client();
|
||
$client->post('https://oauth2.googleapis.com/revoke', [
|
||
'form_params' => [
|
||
'token' => $accessToken,
|
||
],
|
||
]);
|
||
|
||
// 在数据库中删除或标记该`access_token(其实是refresh_token)`为无效
|
||
ThirdUserAdvertiser::where('doc_', $third_user_id)->delete();
|
||
|
||
$tableName = 'bps_third_user';
|
||
$tableName = getenv('DB_PG_SCHEMA') ? getenv('DB_PG_SCHEMA') . '.' . $tableName : 'bps' . $tableName;
|
||
$sql = "UPDATE {$tableName} SET access_token = :access_token WHERE id = :id";
|
||
$data = [
|
||
'access_token' => '', // 这里的 $accessToken 是您想要匹配的值
|
||
'id' => $third_user_id, // 这里的 $accessToken 是您想要匹配的值
|
||
];
|
||
// 执行 SQL 语句
|
||
$result = ThinkDb::execute($sql, $data);
|
||
// ThirdUser::where('access_token', $accessToken)->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'];
|
||
}
|
||
|
||
|
||
/**
|
||
* 批量获取全部Google广告账号数据
|
||
*
|
||
*/
|
||
public function getGoogleAdCustomers($options = [])
|
||
{
|
||
// 获取符合条件的客户ID数组
|
||
$customers = ThirdUserAdvertiser::alias('tua')
|
||
->join('bps.bps_third_user tu', 'tua.doc_ = tu.id') // 连接 bps_third_user 表
|
||
->where('tu.third_type', 'google') // 筛选 third_type 为 google 的记录
|
||
->field('tua.advertiser_id as customer_id,tua.google_login_customer_id as login_customer_id, tu.access_token as refresh_token') // 获取 advertiser_id 字段
|
||
->select(); // 执行查询
|
||
|
||
// 如果没有找到符合条件的广告主,抛出异常
|
||
if ($customers->isEmpty()) {
|
||
return [];
|
||
// throw new ApiException('No customers found for google third type');
|
||
}
|
||
|
||
// 转换为简单的数组(提取 advertiser_id)
|
||
return $customers->toArray();
|
||
|
||
}
|
||
|
||
|
||
} |