未经授权的 WebHook 回调通道
Unauthorized WebHook callback channel
从昨天开始我就一直在为这个问题苦苦挣扎。寻找可以帮助其他遇到类似问题的人的解决方案,但对我没有任何帮助。如果有人能帮助我,我将不胜感激!
我创建了一个项目(名称:xxx),应用引擎(id:app-xxx)监视 GCS 存储桶(名称:bucket-xxx)。 App Engine 和 bucket 在同一个项目中。我尝试按照 here 列出的步骤进行操作:
使用 p12 密钥创建服务帐户(电子邮件:xxx@app-xxx.iam.gserviceaccount.com)。
白名单 URL (属性: https://app-xxx.appspot.com)。我在网站管理员搜索控制台中看到了 URL。我用站长列表API.
的时候也是一样的
注册域名(app-xxx.appspot.com/)
已将 gsutil 配置为使用服务帐户
"gcloud auth activate-service-account xxx@app-xxx.iam.gserviceaccount.com --key-file path/to/key.p12"。使用 "gcloud auth list" 命令验证,报告:
认证帐户:
- xxx@app-xxx.iam.gserviceaccount.com(活跃)
- 授予应用引擎对 GCS 存储桶的完全访问权限
"gsutil acl ch -u app-xxx@appspot.gserviceaccount.com:FC gs://bucket-xxx"
我在开发者控制台的“权限”页面中看到权限列表:
app-xxx@appspot.gserviceaccount.com(App 引擎服务帐户)
我也可以成功将文件从本地计算机上传到 GCS bucket-xxx:
"gsutils cp local-file gs://bucket-xxx/"
但是,当我设置通知时,它报告:
"ServiceException: 401 Unauthorized WebHook callback channel: https://app-xxx.appspot.com/notification"
收到的响应 header 显示以下错误:
"WWW-Authenticate: Bearer realm="https://accounts.google.com/",错误=invalid_token"
知道这里可能有什么问题吗?谢谢!
当您使用不是应用程序默认服务帐户凭据的服务帐户(即您自己创建的,不是应用程序- xxx@appspot.gserviceaccount.com)。由于无法获取此帐户的 p12 密钥,因此您将无法使用 gsutil 添加手表。
您需要做的是从 App Engine 应用程序内部添加手表,使用 JSON API and the application's default service account credentials (AppAssertionCredentials). Here's an incomplete Python example (my default since I don't know which language your app uses) which shows how this might be accomplished which uses the google-api-python-client:
from oauth2client.appengine import AppAssertionCredentials
from httplib2 import Http
from apiclient.discovery import build
credentials = AppAssertionCredentials('https://www.googleapis.com/auth/devstorage.read_only')
http_auth = credentials.authorize(Http())
storage = build('storage', 'v1', http=http_auth)
request = service.objects().watchAll(bucket='mybucket', body={args...})
request.execute()
请参阅 watchAll 的 pydoc。请注意,您需要将应用程序的默认服务帐户添加到存储桶的 ACL 才能正常工作(几乎总是 app-id@appspot.gserviceaccount.com,可在开发者控制台的 'Permissions' 部分查看)。
只是为了扩展 Sevle 的回答:这也会发生 即使您从(例如)Secret Manager 和然后从他们那里创建一个客户端.
在一个用 TypeScript 编写的 Firebase 项目中,我不得不更改我的代码:
return google.auth.getClient({
credentials,
scopes: ['https://www.googleapis.com/auth/calendar'],
})
.then((client) => {
client.subject = settings.get('apiUser');
return google.calendar({
version: 'v3',
auth: client,
});
});
改为这样工作:
return new GoogleAuth({
scopes: ['https://www.googleapis.com/auth/calendar'],
clientOptions: { subject: settings.get('apiUser') },
}).getClient()
.then((client) =>
google.calendar({
version: 'v3',
auth: client,
})
);
请注意,第一个示例中 google.auth.getClient
中的 google
与 npm 上的包 googleapis
捆绑在一起,但第二个示例中使用的 new GoogleAuth
实际上是自带的来自 google-auth-library
.
我们稍微更改了应用程序架构,因此我们不需要针对不同的请求使用不同的服务帐户,所以这现在对我们有用。
从昨天开始我就一直在为这个问题苦苦挣扎。寻找可以帮助其他遇到类似问题的人的解决方案,但对我没有任何帮助。如果有人能帮助我,我将不胜感激!
我创建了一个项目(名称:xxx),应用引擎(id:app-xxx)监视 GCS 存储桶(名称:bucket-xxx)。 App Engine 和 bucket 在同一个项目中。我尝试按照 here 列出的步骤进行操作:
使用 p12 密钥创建服务帐户(电子邮件:xxx@app-xxx.iam.gserviceaccount.com)。
白名单 URL (属性: https://app-xxx.appspot.com)。我在网站管理员搜索控制台中看到了 URL。我用站长列表API.
的时候也是一样的
注册域名(app-xxx.appspot.com/)
已将 gsutil 配置为使用服务帐户 "gcloud auth activate-service-account xxx@app-xxx.iam.gserviceaccount.com --key-file path/to/key.p12"。使用 "gcloud auth list" 命令验证,报告:
认证帐户: - xxx@app-xxx.iam.gserviceaccount.com(活跃)
- 授予应用引擎对 GCS 存储桶的完全访问权限 "gsutil acl ch -u app-xxx@appspot.gserviceaccount.com:FC gs://bucket-xxx"
我在开发者控制台的“权限”页面中看到权限列表: app-xxx@appspot.gserviceaccount.com(App 引擎服务帐户)
我也可以成功将文件从本地计算机上传到 GCS bucket-xxx: "gsutils cp local-file gs://bucket-xxx/"
但是,当我设置通知时,它报告: "ServiceException: 401 Unauthorized WebHook callback channel: https://app-xxx.appspot.com/notification"
收到的响应 header 显示以下错误: "WWW-Authenticate: Bearer realm="https://accounts.google.com/",错误=invalid_token"
知道这里可能有什么问题吗?谢谢!
当您使用不是应用程序默认服务帐户凭据的服务帐户(即您自己创建的,不是应用程序- xxx@appspot.gserviceaccount.com)。由于无法获取此帐户的 p12 密钥,因此您将无法使用 gsutil 添加手表。
您需要做的是从 App Engine 应用程序内部添加手表,使用 JSON API and the application's default service account credentials (AppAssertionCredentials). Here's an incomplete Python example (my default since I don't know which language your app uses) which shows how this might be accomplished which uses the google-api-python-client:
from oauth2client.appengine import AppAssertionCredentials
from httplib2 import Http
from apiclient.discovery import build
credentials = AppAssertionCredentials('https://www.googleapis.com/auth/devstorage.read_only')
http_auth = credentials.authorize(Http())
storage = build('storage', 'v1', http=http_auth)
request = service.objects().watchAll(bucket='mybucket', body={args...})
request.execute()
请参阅 watchAll 的 pydoc。请注意,您需要将应用程序的默认服务帐户添加到存储桶的 ACL 才能正常工作(几乎总是 app-id@appspot.gserviceaccount.com,可在开发者控制台的 'Permissions' 部分查看)。
只是为了扩展 Sevle 的回答:这也会发生 即使您从(例如)Secret Manager 和然后从他们那里创建一个客户端.
在一个用 TypeScript 编写的 Firebase 项目中,我不得不更改我的代码:
return google.auth.getClient({
credentials,
scopes: ['https://www.googleapis.com/auth/calendar'],
})
.then((client) => {
client.subject = settings.get('apiUser');
return google.calendar({
version: 'v3',
auth: client,
});
});
改为这样工作:
return new GoogleAuth({
scopes: ['https://www.googleapis.com/auth/calendar'],
clientOptions: { subject: settings.get('apiUser') },
}).getClient()
.then((client) =>
google.calendar({
version: 'v3',
auth: client,
})
);
请注意,第一个示例中 google.auth.getClient
中的 google
与 npm 上的包 googleapis
捆绑在一起,但第二个示例中使用的 new GoogleAuth
实际上是自带的来自 google-auth-library
.
我们稍微更改了应用程序架构,因此我们不需要针对不同的请求使用不同的服务帐户,所以这现在对我们有用。