从 Google Apps 脚本访问经过身份验证的 Google Cloud Endpoints API
Accessing authenticated Google Cloud Endpoints API from Google Apps Script
我正在尝试从使用 Google 云端点构建的 API 中将一些数据提取到 Google 工作表电子表格中。这是 API 声明:
@Api(
name = "myendpoint",
namespace =
@ApiNamespace
(
ownerDomain = "mydomain.com",
ownerName = "mydomain.com",
packagePath = "myapp.model"
),
scopes = {SCOPES},
clientIds = {ANDROID_CLIENT_ID, WEB_CLIENT_ID, API_EXPLORER_CLIENT_ID},
audiences = {WEB CLIENT_ID}
)
我尝试访问的方法通过 API 声明中的用户参数启用了身份验证:
@ApiMethod(name = "ping", httpMethod = HttpMethod.GET, path = "ping")
public StringResponse getPing(User user) throws OAuthRequestException {
CheckPermissions(user);//throws an exception if the user is null or doesn't have the correct permissions
return new StringResponse("pong");
}
这在使用生成的客户端库或 gapi js 库时工作正常。但是 AFAIK 我不能在 Apps 脚本中使用那些 js 库。
我使用来自 here 的 apps-script-oauth2 库获得了一个 OAuth2 流程,并且我几乎使用默认设置来创建服务
function getService() {
// Create a new service with the given name. The name will be used when
// persisting the authorized token, so ensure it is unique within the
// scope of the property store.
return OAuth2.createService(SERVICE_NAME)
// Set the endpoint URLs, which are the same for all Google services.
.setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth')
.setTokenUrl('https://accounts.google.com/o/oauth2/token')
// Set the client ID and secret, from the Google Developers Console.
.setClientId(CLIENT_ID)
.setClientSecret(CLIENT_SECRET)
// Set the name of the callback function in the script referenced
// above that should be invoked to complete the OAuth flow.
.setCallbackFunction('ruggedAuthCallback')
// Set the property store where authorized tokens should be persisted.
.setPropertyStore(PropertiesService.getUserProperties())
// Set the scopes to request (space-separated for Google services).
.setScope(SCOPES)
// Below are Google-specific OAuth2 parameters.
// Sets the login hint, which will prevent the account chooser screen
// from being shown to users logged in with multiple accounts.
.setParam('login_hint', Session.getActiveUser().getEmail())
// Requests offline access.
.setParam('access_type', 'offline')
// Forces the approval prompt every time. This is useful for testing,
// but not desirable in a production application.
.setParam('approval_prompt', 'auto')
//.setParam('include_granted_scopes', 'true');
}
这些是我访问 APIs
的方法
function getDriveDocs() {
return executeApiMethod('https://www.googleapis.com/drive/v2/','files?maxResults=10');
}
function pingServer(){
return executeApiMethod('https://myapp.appspot.com/_ah/api/myendpoint/v1/','ping');
}
function executeApiMethod(apiUrl, method)
{
//var url = ;
var url = apiUrl + method;
var service = getRuggedService();
return UrlFetchApp.fetch(url, {
'muteHttpExceptions': true,
'method': 'get',
'headers': {
Authorization: 'Bearer ' + service.getAccessToken()
}
});
}
getDriveDocs() 方法运行良好,所以我知道我的身份验证流程运行正常。此外,如果我在 API 中调用未经身份验证的方法,我会得到正确的响应。但是,当我调用经过身份验证的 'ping' 方法时, 'user' 参数始终为空。我在 fetch 调用中遗漏了什么吗?到目前为止我读过的所有内容似乎都表明设置
Authorization: 'Bearer ' + service.getAccessToken()
应该够了。
如有任何帮助,我们将不胜感激!
结果证明这是一个简单的错误 - 我在 google 开发控制台中创建了一个新的 oauth2 凭证,并且没有将新的客户端 ID 添加到 API 声明中。这是有效的 API 声明:
@Api(
name = "myendpoint",
namespace =
@ApiNamespace
(
ownerDomain = "mydomain.com",
ownerName = "mydomain.com",
packagePath = "myapp.model"
),
scopes = {SCOPES},
clientIds = {ANDROID_CLIENT_ID, WEB_CLIENT_ID, API_EXPLORER_CLIENT_ID, GAPPS_CLIENT_ID},
audiences = {WEB CLIENT_ID}
)
我正在尝试从使用 Google 云端点构建的 API 中将一些数据提取到 Google 工作表电子表格中。这是 API 声明:
@Api(
name = "myendpoint",
namespace =
@ApiNamespace
(
ownerDomain = "mydomain.com",
ownerName = "mydomain.com",
packagePath = "myapp.model"
),
scopes = {SCOPES},
clientIds = {ANDROID_CLIENT_ID, WEB_CLIENT_ID, API_EXPLORER_CLIENT_ID},
audiences = {WEB CLIENT_ID}
)
我尝试访问的方法通过 API 声明中的用户参数启用了身份验证:
@ApiMethod(name = "ping", httpMethod = HttpMethod.GET, path = "ping")
public StringResponse getPing(User user) throws OAuthRequestException {
CheckPermissions(user);//throws an exception if the user is null or doesn't have the correct permissions
return new StringResponse("pong");
}
这在使用生成的客户端库或 gapi js 库时工作正常。但是 AFAIK 我不能在 Apps 脚本中使用那些 js 库。
我使用来自 here 的 apps-script-oauth2 库获得了一个 OAuth2 流程,并且我几乎使用默认设置来创建服务
function getService() {
// Create a new service with the given name. The name will be used when
// persisting the authorized token, so ensure it is unique within the
// scope of the property store.
return OAuth2.createService(SERVICE_NAME)
// Set the endpoint URLs, which are the same for all Google services.
.setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth')
.setTokenUrl('https://accounts.google.com/o/oauth2/token')
// Set the client ID and secret, from the Google Developers Console.
.setClientId(CLIENT_ID)
.setClientSecret(CLIENT_SECRET)
// Set the name of the callback function in the script referenced
// above that should be invoked to complete the OAuth flow.
.setCallbackFunction('ruggedAuthCallback')
// Set the property store where authorized tokens should be persisted.
.setPropertyStore(PropertiesService.getUserProperties())
// Set the scopes to request (space-separated for Google services).
.setScope(SCOPES)
// Below are Google-specific OAuth2 parameters.
// Sets the login hint, which will prevent the account chooser screen
// from being shown to users logged in with multiple accounts.
.setParam('login_hint', Session.getActiveUser().getEmail())
// Requests offline access.
.setParam('access_type', 'offline')
// Forces the approval prompt every time. This is useful for testing,
// but not desirable in a production application.
.setParam('approval_prompt', 'auto')
//.setParam('include_granted_scopes', 'true');
}
这些是我访问 APIs
的方法function getDriveDocs() {
return executeApiMethod('https://www.googleapis.com/drive/v2/','files?maxResults=10');
}
function pingServer(){
return executeApiMethod('https://myapp.appspot.com/_ah/api/myendpoint/v1/','ping');
}
function executeApiMethod(apiUrl, method)
{
//var url = ;
var url = apiUrl + method;
var service = getRuggedService();
return UrlFetchApp.fetch(url, {
'muteHttpExceptions': true,
'method': 'get',
'headers': {
Authorization: 'Bearer ' + service.getAccessToken()
}
});
}
getDriveDocs() 方法运行良好,所以我知道我的身份验证流程运行正常。此外,如果我在 API 中调用未经身份验证的方法,我会得到正确的响应。但是,当我调用经过身份验证的 'ping' 方法时, 'user' 参数始终为空。我在 fetch 调用中遗漏了什么吗?到目前为止我读过的所有内容似乎都表明设置
Authorization: 'Bearer ' + service.getAccessToken()
应该够了。
如有任何帮助,我们将不胜感激!
结果证明这是一个简单的错误 - 我在 google 开发控制台中创建了一个新的 oauth2 凭证,并且没有将新的客户端 ID 添加到 API 声明中。这是有效的 API 声明:
@Api(
name = "myendpoint",
namespace =
@ApiNamespace
(
ownerDomain = "mydomain.com",
ownerName = "mydomain.com",
packagePath = "myapp.model"
),
scopes = {SCOPES},
clientIds = {ANDROID_CLIENT_ID, WEB_CLIENT_ID, API_EXPLORER_CLIENT_ID, GAPPS_CLIENT_ID},
audiences = {WEB CLIENT_ID}
)