向 Google 日历 API 发出服务器到服务器请求
Making server to server request to Google Calendar API
我正在使用 vue.js 构建一个 SPA,它有一个 PHP后端服务器(slim framework 3)。这是两个独立的项目,放在两台不同的服务器上,后端根本没有前端。
SPA (vue.js) 通过 ajax 向后端发出请求。
现在我想实现 Google 日历 API 以在用户每次创建待办事项时创建一个日历和事件。为此,我需要服务器到服务器访问 Google 日历 API(即使用户未登录,我也可能需要对 GCAL 上的事件进行更改)。
我想了解的是,如何使用 vue.js 使用 Google JS 库获取访问令牌(和刷新令牌)并将其保存在数据库中以便我的后端可以使用它向 GCAL Api.
发出离线请求
当我使用 JS 库使用 Oauth v.2 时,我得到的只是 access_token,它不能用于服务器到服务器的通信。
[更新]
好的,更多信息。我正在按照 Google 的指南进行操作,目前我的前端看起来像这样
jsbin
所以我可以成功授权用户并使用 javascript sdk 访问他们的日历。但是令牌 Javascript SDK returns 是这样的
{
_aa: "1"
access_token: "xxxxxxx"
client_id: "yyyyyyyyyy"
cookie_policy: undefined
expires_at: "1456400189"
expires_in: "3600"
g_user_cookie_policy: undefined
issued_at: "1456396589"
response_type: "token"
scope: "https://www.googleapis.com/auth/calendar"
state: ""
status: Object
google_logged_in: false
method: "AUTO"
signed_in: true
token_type: "Bearer"
}
我将此令牌发送到我的后端服务器并尝试向 GCAL api 发出如下请求
$token = $request->getParam('token');
$client = new Google_Client();
$client->setApplicationName('Web');
$client->setScopes([Google_Service_Calendar::CALENDAR]);
$client->setAuthConfigFile(ROOT_DIR . '/client_secret.json');
$client->setAccessType('offline');
$client->setAccessToken(json_encode($token));
$service = new Google_Service_Calendar($client);
$calendarId = 'primary';
$optParams = array(
'maxResults' => 10,
'orderBy' => 'startTime',
'singleEvents' => TRUE,
'timeMin' => date('c'),
);
$results = $service->events->listEvents($calendarId, $optParams);
它 returns 错误提示令牌已过期。我检查了 Google 代码并找出了 returns 这个错误的原因是这些行
public function isAccessTokenExpired()
{
if (!$this->token || !isset($this->token['created'])) {
return true;
}
// If the token is set to expire in the next 30 seconds.
$expired = ($this->token['created']
+ ($this->token['expires_in'] - 30)) < time();
return $expired;
}
如您所见,来自前端的令牌没有 created
字段,也没有 refresh_token
字段。
感谢您更新问题!我认为问题在于使用客户端流程不允许您获得刷新令牌。来自文档:
OAuth 2.0 client-side flow (AKA Implicit flow) is used to obtain
access tokens (it does not support the issuance of refresh tokens) and
is optimized for public clients known to operate a particular
redirection URI. These clients are typically implemented in a browser
using a scripting language such as JavaScript.
The authorization server MUST NOT issue a refresh token.
查看更多:How to get refresh token while using Google API JS Client
您需要使用服务器身份验证流程来获取可以刷新和长期使用的令牌。 Here's a quickstart guide for PHP.
另一件需要考虑的事情是,您只会在第一次有人授权您的应用时收到refresh_token
。之后,身份验证尝试将仅 return 一个访问令牌。因此,如果您丢失了刷新令牌,则需要禁用 google 帐户的授权,或使用 API.
中的 "force re-auth" 选项
我正在使用 vue.js 构建一个 SPA,它有一个 PHP后端服务器(slim framework 3)。这是两个独立的项目,放在两台不同的服务器上,后端根本没有前端。
SPA (vue.js) 通过 ajax 向后端发出请求。
现在我想实现 Google 日历 API 以在用户每次创建待办事项时创建一个日历和事件。为此,我需要服务器到服务器访问 Google 日历 API(即使用户未登录,我也可能需要对 GCAL 上的事件进行更改)。
我想了解的是,如何使用 vue.js 使用 Google JS 库获取访问令牌(和刷新令牌)并将其保存在数据库中以便我的后端可以使用它向 GCAL Api.
发出离线请求当我使用 JS 库使用 Oauth v.2 时,我得到的只是 access_token,它不能用于服务器到服务器的通信。
[更新]
好的,更多信息。我正在按照 Google 的指南进行操作,目前我的前端看起来像这样 jsbin
所以我可以成功授权用户并使用 javascript sdk 访问他们的日历。但是令牌 Javascript SDK returns 是这样的
{
_aa: "1"
access_token: "xxxxxxx"
client_id: "yyyyyyyyyy"
cookie_policy: undefined
expires_at: "1456400189"
expires_in: "3600"
g_user_cookie_policy: undefined
issued_at: "1456396589"
response_type: "token"
scope: "https://www.googleapis.com/auth/calendar"
state: ""
status: Object
google_logged_in: false
method: "AUTO"
signed_in: true
token_type: "Bearer"
}
我将此令牌发送到我的后端服务器并尝试向 GCAL api 发出如下请求
$token = $request->getParam('token');
$client = new Google_Client();
$client->setApplicationName('Web');
$client->setScopes([Google_Service_Calendar::CALENDAR]);
$client->setAuthConfigFile(ROOT_DIR . '/client_secret.json');
$client->setAccessType('offline');
$client->setAccessToken(json_encode($token));
$service = new Google_Service_Calendar($client);
$calendarId = 'primary';
$optParams = array(
'maxResults' => 10,
'orderBy' => 'startTime',
'singleEvents' => TRUE,
'timeMin' => date('c'),
);
$results = $service->events->listEvents($calendarId, $optParams);
它 returns 错误提示令牌已过期。我检查了 Google 代码并找出了 returns 这个错误的原因是这些行
public function isAccessTokenExpired()
{
if (!$this->token || !isset($this->token['created'])) {
return true;
}
// If the token is set to expire in the next 30 seconds.
$expired = ($this->token['created']
+ ($this->token['expires_in'] - 30)) < time();
return $expired;
}
如您所见,来自前端的令牌没有 created
字段,也没有 refresh_token
字段。
感谢您更新问题!我认为问题在于使用客户端流程不允许您获得刷新令牌。来自文档:
OAuth 2.0 client-side flow (AKA Implicit flow) is used to obtain access tokens (it does not support the issuance of refresh tokens) and is optimized for public clients known to operate a particular redirection URI. These clients are typically implemented in a browser using a scripting language such as JavaScript.
The authorization server MUST NOT issue a refresh token.
查看更多:How to get refresh token while using Google API JS Client
您需要使用服务器身份验证流程来获取可以刷新和长期使用的令牌。 Here's a quickstart guide for PHP.
另一件需要考虑的事情是,您只会在第一次有人授权您的应用时收到refresh_token
。之后,身份验证尝试将仅 return 一个访问令牌。因此,如果您丢失了刷新令牌,则需要禁用 google 帐户的授权,或使用 API.