- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
由于 Google 登录身份验证自上周起被禁用,我正在尝试让 oAuth 2.0 使用服务帐户。我们希望为我们内部网络应用程序的用户提供设置外出的机会。
我下载了最新的Google APIs Client Library for PHP .在Google Developer Console ,我为我的应用程序创建了一个新项目并创建了一个 Service account
凭据。我还在开发者控制台中启用了 API 服务:Admin SDK
。
我已授予帐户用户 ID 访问正确范围的权限(我认为):
当我使用 service-account.php 示例并更改详细信息时,我会收到带有访问 token 的 JSON,但是当我执行 CURL 请求(与之前相同)以从用户那里获取电子邮件设置时,出现错误 “您无权访问此 API。”
。
我的代码:
<?php
include_once "templates/base.php";
require_once realpath(dirname(__FILE__) . '/../src/Google/autoload.php');
$client_id = '124331845-DELETEDPART-hbh89pbgl20citf6ko.apps.googleusercontent.com'; //Client ID
$service_account_name = '124331845-DELETEDPART-89pbgl20citf6ko@developer.gserviceaccount.com'; //Email Address
$key_file_location = 'globaltext-4ce09b20cb73.p12'; //key.p12
$client = new Google_Client();
if (isset($_SESSION['service_token'])) {
$client->setAccessToken($_SESSION['service_token']);
}
$key = file_get_contents($key_file_location);
$cred = new Google_Auth_AssertionCredentials(
$service_account_name,
array('https://apps-apis.google.com/a/feeds/emailsettings/2.0/'),
$key
);
$client->setAssertionCredentials($cred);
if ($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($cred);
}
$aOutput = json_decode($client->getAccessToken());
$strEmailAdresSplit = explode('@', "FIRSTNAME.LASTNAME@DOMAIN.EXTENSION");
$strDomein = $strEmailAdresSplit[1];
$strAlias = $strEmailAdresSplit[0];
$resConnectionJobs = curl_init();
$aHeader = array();
$aHeader[] = 'Authorization: Bearer '.$aOutput->access_token;
$aHeader[] = 'Content-Type: application/atom+xml';
curl_setopt($resConnectionJobs, CURLOPT_URL, "https://apps-apis.google.com/a/feeds/emailsettings/2.0/DOMAIN.EXTENSION/FIRSTNAME.LASTNAME/vacation");
curl_setopt($resConnectionJobs, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($resConnectionJobs, CURLOPT_HTTPHEADER, $aHeader);
curl_setopt($resConnectionJobs, CURLOPT_RETURNTRANSFER, true);
curl_setopt($resConnectionJobs, CURLOPT_HEADER, false);
$oCurlData = curl_exec($resConnectionJobs);
curl_close($resConnectionJobs);
echo $oCurlData;
?>
最佳答案
您确定您的凭据没问题吗?
请尝试以下过程以确保您拥有正确的凭据。
创建您的 API key
转到 developer's console并按照以下步骤操作:
获取访问 token 和刷新 token
创建一个包含以下代码的文件:
<?php
if (isset($_GET['code'])) {
// try to get an access token
$code = $_GET['code'];
$url = 'https://accounts.google.com/o/oauth2/token';
$params = array(
"code" => $code,
"client_id" => YOUR_CLIENT_ID,
"client_secret" => YOUR_CLIENT_SECRET,
"redirect_uri" => 'http://' . $_SERVER["HTTP_HOST"] . $_SERVER["PHP_SELF"],
"grant_type" => "authorization_code"
);
$ch = curl_init();
curl_setopt($ch, constant("CURLOPT_" . 'URL'), $url);
curl_setopt($ch, constant("CURLOPT_" . 'POST'), true);
curl_setopt($ch, constant("CURLOPT_" . 'POSTFIELDS'), $params);
$output = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
if ($info['http_code'] === 200) {
header('Content-Type: ' . $info['content_type']);
return $output;
} else {
return 'An error happened';
}
} else {
$url = "https://accounts.google.com/o/oauth2/auth";
$params = array(
"response_type" => "code",
"client_id" => YOUR_CLIENT_ID,
"redirect_uri" => 'http://' . $_SERVER["HTTP_HOST"] . $_SERVER["PHP_SELF"],
"scope" => "https://www.googleapis.com/auth/plus.me"
);
$request_to = $url . '?' . http_build_query($params);
header("Location: " . $request_to);
}
现在,将 YOUR_CLIENT_ID
和 YOUR_CLIENT_SECRET
替换为您的客户端 ID 和客户端密码。
确保您的范围是正确的。例如,如果您想访问 Analytics,它应该是 https://www.googleapis.com/auth/analytics
。
如果您运行该文件,您应该会看到一个 OAuth2 批准屏幕。
如果您现在按接受
,您应该得到如下所示的结果:
{
"access_token" : YOUR_ACCESS_TOKEN,
"token_type" : "Bearer",
"expires_in" : 3600,
"refresh_token" : YOUR_REFRESH_TOKEN
}
结果可能包含其他字段,具体取决于您申请的范围。
在后台连接 Google 的系统
完成上述工作后,您的应用程序需要实现以下工作流程:
1) 检查您的输入是否包含名为“code”的 GET 参数。如果存在“代码”,请获取新的访问 token 并重复此步骤(刷新您的页面)如果“代码”不存在,转到步骤 2。
2) 检查您是否为您的服务存储了凭据。如果存在凭据,请检查您的访问 token 是否已过期或即将过期。然后转到第 3 步。如果凭据不存在,请转到您服务的授权路径以获取授权代码并返回到第 1 步(确保 Google 重定向到您当前的 URL)。
3) 如果需要刷新,请刷新您的页面并返回步骤 1。如果不需要刷新,您就可以真正开始做您想做的事了。
但是,Google 的 PHP 库会为您处理 oAuth2 流程。如果您使用的是他们的图书馆,则三步流程中的每一步都由图书馆负责,您应该可以立即使用 Google 的服务做任何您想做的事情。我自己在 my Google Adwords dashboard 中使用了这个策略.
但是,您可以只编写自定义库并直接连接服务。下面是我几个月前写的一个项目的一些开发代码。虽然它不是开箱即用的(因为它是一个较大应用程序的一部分的 Controller ),但它应该可以帮助您了解 Google 的库在幕后处理的流程。
namespace Application;
class Controller_API_Google_Youtube extends Controller_API {
public function read() {
$scope = "https://www.googleapis.com/auth/youtube";
$this->doOauth($scope);
}
function doOauth($scope) {
$oauth2Credentials = JSON_File::load(__DIR__ . DIRECTORY_SEPARATOR . 'Config.json');
$paths = array(
'token' => 'https://accounts.google.com/o/oauth2/token',
'auth' => "https://accounts.google.com/o/oauth2/auth"
);
$refreshtime = 300;
if (isset($_GET['code'])) {
// Get access code
$query = $_GET;
unset($query['code']);
if (count($query) > 0) {
$query = '?' . http_build_query($query);
} else {
$query = '';
}
$client = \PowerTools\HTTP_Client::factory(
array(
'maps' => array(
'url' => $paths['token'],
'returntransfer' => 1,
'post' => true,
'postfields' => array(
'code' => $_GET['code'],
"client_id" => $oauth2Credentials['client_id'],
"client_secret" => $oauth2Credentials['client_secret'],
"redirect_uri" => HTTP_PROTOCOL . URL_PATH . $query,
"grant_type" => "authorization_code"
)
)
)
)->execute();
$responses = $client->getResponses();
$response = array_pop($responses);
$info = $response['maps']->getInfo();
$content = $response['maps']->getContent();
if ($info['http_code'] === 200) {
$output = JSON::decode($content);
$oauth2Credentials[$scope] = array();
$oauth2Credentials[$scope]['expires'] = time() + $output['expires_in'];
$oauth2Credentials[$scope]['access_token'] = $output['access_token'];
$oauth2Credentials[$scope]['refresh_token'] = $output['refresh_token'];
file_put_contents(__DIR__ . DIRECTORY_SEPARATOR . 'Config.json', JSON::encode($oauth2Credentials));
header("Location: " . HTTP_PROTOCOL . URL_PATH . $query);
} else {
echo "Something went wrong";
}
} elseif (!isset($oauth2Credentials[$scope])) {
// Get auth code
header("Location: " . $paths['auth'] . '?' . http_build_query(
array(
"response_type" => "code",
"client_id" => $oauth2Credentials['client_id'],
"redirect_uri" => HTTP_PROTOCOL . DOMAIN_PATH,
"scope" => $scope
)
));
} elseif ($oauth2Credentials[$scope]['expires'] - $refreshtime < time()) {
// Refresh access code
$client = \PowerTools\HTTP_Client::factory(
array(
'maps' => array(
'url' => $paths['token'],
'returntransfer' => 1,
'post' => true,
'postfields' => array(
"client_id" => $oauth2Credentials['client_id'],
"client_secret" => $oauth2Credentials['client_secret'],
"refresh_token" => $oauth2Credentials[$scope]['refresh_token'],
"grant_type" => "refresh_token"
)
)
)
)->execute();
$responses = $client->getResponses();
$response = array_pop($responses);
$info = $response['maps']->getInfo();
$content = $response['maps']->getContent();
if ($info['http_code'] === 200) {
$output = JSON::decode($response['maps']->getContent());
$oauth2Credentials[$scope]['expires'] = time() + $output['expires_in'];
$oauth2Credentials[$scope]['access_token'] = $output['access_token'];
file_put_contents(__DIR__ . DIRECTORY_SEPARATOR . 'Config.json', JSON::encode($oauth2Credentials));
$this->read();
} else {
$this->output = array("error" => "Something went wrong");
}
} else {
$this->doSomethinguseful($oauth2Credentials, $scope);
}
return $this;
}
function doSomethinguseful($oauth2Credentials, $scope) {
// https://developers.google.com/youtube/v3/sample_requests?hl=nl
$client = \PowerTools\HTTP_Client::factory(
array(
'maps' => array(
'useragent' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13',
'url' => 'https://www.googleapis.com/youtube/v3/channels?part=contentDetails&mine=true',
'returntransfer' => true,
'httpheader' => array(
'Authorization: Bearer ' . $oauth2Credentials[$scope]['access_token'],
'Accept-Encoding: gzip, deflate'
)
)
)
)->execute();
$responses = $client->getResponses();
$response = array_pop($responses);
$content = $response['maps']->getContent();
$this->output = JSON::decode(gzdecode($content));
}
}
关于php - 谷歌管理员 SDK : You are not authorized to access this API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30569681/
我目前有一个使用 Authorize.net 的 ARB API 的应用程序。我的一切都按照我认为应该的方式工作,但我真的很想收到来自 authorize.net 测试服务器 (test.author
Authorize.net 永远不会允许您退还同一天提交的交易。因此,编写一个创建交易然后退款的测试是很困难的。 我找不到通过 API 执行此操作的方法,因此: 我可以要求 Authorize.net
我想使用 createTransactionRequest 创建付款资料。 这是我传递的请求参数。 { "createTransactionRequest":{ "merchantA
我根据这个例子开发了我的mvc应用程序: https://github.com/AzureADSamples/WebApp-WebAPI-OpenIDConnect-DotNet 身份验证与 Azur
所以我正在尝试实现以下场景: 应用程序受基本身份验证保护。假设它托管在 app.com 上 在应用程序前面的 HTTP 代理也需要身份验证。它托管在 proxy.com 因此,用户必须在同一个请求中为
根据 ASP.NET website ASP.NET MVC 框架包括几个 Action 过滤器: OutputCache – 此操作过滤器将 Controller 操作的输出缓存一段指定的时间。 H
我正在发布一些 JSON 数据并添加一个 Authorization标题。但是,请求对象没有正确的授权属性。 HTTP_AUTHORIZATION和 headers两者都显示正确的授权详细信息。 {'
更改群集的IP配置(所有外部IP更改,内部专用IP保持不变)后,某些kubectl命令不再对任何容器起作用。 pods 全部启动并运行,似乎发现自己没有问题。这是输出: bronger@penny:~
Authorize.Net will be upgrading access to the Internet connections that serve our data centers. Inst
您好,我正在学习 HTML5,我想知道这两个元元素之间有什么区别? 最佳答案 第一个无效,http-equiv被枚举,即它有一组对其有效的值和author不是一个。 (它旨在作为一种将 pragm
我们想在应用商店中发布一个应用。为我们构建它的第 3 方需要我们通过苹果开发门户创建的证书和配置文件。根据文档,创建证书的方法是使用 mac 的钥匙串(keychain)应用程序,然后选择“从证书颁发
在同一项目中,在 Nancy 中使用任一 token 授权形式保护模块的最佳方法是什么?我需要两种类型的安全性,并且我不希望创建单独的应用程序:一种使用 Form 保护 View ,另一种用于使用 T
我正在尝试获取访问 token ,但是我收到了这个错误 {"error_description":"授权服务器不支持授权授予类型","error":"unsupported_grant_type"}
如何从一组“author”(User)中过滤出具有“author”的对象? “对象”是帖子,具有作者(ForeignKey 到用户)。 我对此非常困惑,所以我很感激能得到帮助。当然,人们可以通过手动过
我有三个 Kafka 经纪人( kafka_2.11-0.10.0.0 )每个经纪人的安全配置如下, listeners=PLAINTEXT://xxxx:9093,SASL_PLAINTEXT://
@IBOutlet weak var menuButton: UIButton! @IBOutlet weak var clubButton: UIButton! @IBOutlet weak var
我不知道如何执行以下查询。我有 3 张 table : song (song_id, title, is_draft) author (author_id, name) song_author (so
我正在使用 Thymeleaf、Spring-boot 和 Java。我有导航栏的 li 项目,并且想要为其中一个 li 项目设置访问权限,以便如果 LoggedUser.client.policyT
刚从使用 Books 应用程序示例的 Djangobook 教程中学习时,您通过多对多关系将 Book 与 Author 相关,并将 Book 与 Publisher 相关。您可以使用 p.book_
当我的应用程序启动 map View 时,我请求 iOS8“使用时”位置权限。假设用户同意。 仅当用户选择加入我的地理围栏功能时,我才想请求始终许可。但是调用 CLLocationManager.re
我是一名优秀的程序员,十分优秀!