无法使用服务帐户授权连接到自己的 GAE 端点 API

2024-02-07

我一直在拼命尝试成功授权对我使用 OAuth2 和服务帐户从 python 脚本运行的 Google App Engine (GAE) 项目的 API 访问。

我创建了服务帐户,将服务帐户 ID 添加到 api 文件中允许的客户端 ID,将私钥从 .p12 转换为 .pem,并授权 httplib2 调用。我尝试使用 .authorize() 方法传递凭据,并通过将凭据加载为 JSON 并手动将 access_token 参数添加到标头中 -{"Authorization": "Bearer " + token_string}.

每次调用 API 都会产生“无效令牌”。

我注意到一件奇怪的事情,当我第一次调用 SignedJwtAssertionCredentials 时,凭证中没有访问令牌——“access_token”为 None。但是,当我从存储中的 .dat 文件检索凭据时,访问令牌确实会显示。

以下是 GAE endpoints_api.py 文件、python_test.py 文件和 401 响应。

任何想法将不胜感激。

首先是应用程序引擎端点服务器文件:

# endpoints_api.py running on GAE

import endpoints
import time
from protorpc import messages
from protorpc import message_types
from protorpc import remote

SERVICE_ACCOUNT_ID = 'random_account_id_string.apps.googleusercontent.com'
WEB_CLIENT_ID = 'random_web_client_id_string.apps.googleusercontent.com'
ANDROID_AUDIENCE = WEB_CLIENT_ID

package = "MyPackage"

class Status(messages.Message):
    message = messages.StringField(1)
    when = messages.IntegerField(2)

class StatusCollection(messages.Message):
    items = messages.MessageField(Status, 1, repeated=True)

STORED_STATUSES = StatusCollection(items=[
    Status(message='Go.', when=int(time.time())),
    Status(message='Balls.', when=int(time.time())),
    Status(message='Deep!', when=int(time.time())),
])

@endpoints.api(name='myserver', version='v1')
class MyServerApi(remote.Service):
    """MyServer API v1."""

    @endpoints.method(message_types.VoidMessage, StatusCollection,
                  allowed_client_ids=[SERVICE_ACCOUNT_ID,
                                      endpoints.API_EXPLORER_CLIENT_ID],
                  audiences=[ANDROID_AUDIENCE],
                  scopes=[endpoints.EMAIL_SCOPE],
                  path='status', http_method='GET',
                  name='statuses.listStatus')
    def statuses_list(self, unused_request):
        current_user = endpoints.get_current_user()
        if current_user is None:
            raise endpoints.UnauthorizedException('Invalid token.')
        else:
            return current_user.email(), STORED_STATUSES

APPLICATION = endpoints.api_server([MyServerApi])

接下来是本地 python 脚本:

# python_test.py file running from local server

from apiclient.discovery import build
from oauth2client.file import Storage
from oauth2client.client import SignedJwtAssertionCredentials
import httplib2
import os.path
import json

SERVICE_ACCOUNT_EMAIL = "[email protected] /cdn-cgi/l/email-protection"
ENDPOINT_URL = "http://my-project.appspot.com/_ah/api/myserver/v1/status"
SCOPE = 'https://www.googleapis.com/auth/userinfo.email'
SITE_ROOT = os.path.dirname(os.path.realpath(__file__))

f = file('%s/%s' % (SITE_ROOT, 'pk2.pem'), 'rb')
key = f.read()
f.close()

http = httplib2.Http()
storage = Storage('credentials.dat')
credentials = storage.get()

if credentials is None or credentials.invalid:
    credentials = SignedJwtAssertionCredentials(
        SERVICE_EMAIL, key, scope=SCOPE)
    storage.put(credentials)
else:
    credentials.refresh(http)

http = credentials.authorize(http)
headers = {'Content-Type': 'application/json'}

(resp, content) = http.request(ENDPOINT_URL,
                           "GET",
                           headers=headers)

print(resp)
print(content)

最后控制台输出:

{'status': '401', 'alternate-protocol': '443:quic,p=0.002', 'content-length': '238', 'x- xss-protection': '1; mode=block', 'x-content-type-options': 'nosniff', 'transfer-encoding': 'chunked', 'expires': 'Sun, 14 Sep 2014 23:51:36 GMT', 'server': 'GSE', '-content-encoding': 'gzip', 'cache-control': 'private, max-age=0', 'date': 'Sun, 14 Sep 2014 23:51:36 GMT', 'x-frame-options': 'SAMEORIGIN', 'content-type': 'application/json; charset=UTF-8', 'www-authenticate': 'Bearer realm="https://accounts.google.com/AuthSubRequest"'}

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "required",
    "message": "Invalid token.",
    "locationType": "header",
    "location": "Authorization"
   }
  ],
  "code": 401,
  "message": "Invalid token."
 }
}

感谢您的帮助。上面有几件事我做错了。

首先,我需要在允许的 ID 列表中引用应用程序引擎项目 ID。

API_ID = 'project-id-number.apps.googleusercontent.com'

@endpoints.method(message_types.VoidMessage, StatusCollection,
              allowed_client_ids=[API_ID, SERVICE_ACCOUNT_ID,
                                  endpoints.API_EXPLORER_CLIENT_ID],
              audiences=[ANDROID_AUDIENCE],
              scopes=[endpoints.EMAIL_SCOPE],
              path='status', http_method='GET',
              name='statuses.listStatus')

我错误地认为 build() 方法只能与官方 google APIS 一起使用,但事实证明我错误地引用了我的项目。有了项目 ID,我可以使用 build() 而不是在服务器端文件中编写我自己的 httplib2 调用(这不起作用)。

删除“http =credentials.authorize(http)”下面的代码,我将其替换为以下内容:

myservice = build('my-service', 'v1', http=http, discoveryServiceUrl=discoveryServiceUrl)
data = myservice.my-path().endpoint-name()
results = data.execute()

这成功授权了我的帐户并调用端点。哇!如果其他人对此有疑问,或者我的解决方案不清楚,请随时发表评论。这是一个痛苦的过程,我不希望其他人也经历这样的过程。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

无法使用服务帐户授权连接到自己的 GAE 端点 API 的相关文章

  • 如何在保留矩阵维度的同时序列化 numpy 数组?

    numpy array tostring似乎没有保留有关矩阵维度的信息 请参阅这个问题 https stackoverflow com q 30697769 1156707 要求用户发出调用numpy array reshape 有没有办法
  • 使用“iloc”时出现“尝试在 DataFrame 切片的副本上设置值”错误

    Jupyter 笔记本返回此警告 C anaconda lib site packages pandas core indexing py 337 SettingWithCopyWarning A value is trying to be
  • 如何选择单选按钮?

    我在用mechanize我正在尝试从单选按钮列表中选择一个按钮 该列表有 5 项 如何选择第一项 文档没有帮助我 gt gt gt br form
  • Django管理命令是在单独的进程中执行的吗?

    Django 有很多管理命令 此外 我们还可以编写自己的命令 进行 shell 调用后会发生什么python manage py XXX 代码是否会在从 shell 启动的进程中执行 或者 shell 进程只是与执行命令的主 Django
  • 使用Python选择屏幕区域

    我正在用 Python 开发一个屏幕截图实用程序 目前它是专门针对 Linux 的 到目前为止 我已经能够拍摄完整桌面的屏幕截图 并将其上传到 Imgur 然后将链接复制到剪贴板 现在我想扩展到诸如活动窗口或特定选择的屏幕截图之类的功能 如
  • 为什么 Python 中的无分支函数和内置函数速度较慢?

    我发现了 2 个无分支函数 它们可以在 python 中查找两个数字的最大值 并将它们与 if 语句和内置 max 函数进行比较 我认为无分支或内置函数将是最快的 但最快的是 if 语句函数 有人知道这是为什么吗 以下是功能 If 语句 2
  • 我应该将Python的pyc文件添加到.dockerignore吗?

    我见过几个例子 dockerignorePython 项目的文件 其中 pyc文件和 或 pycache 文件夹被忽略 pycache pyc 由于无论如何这些文件 文件夹都会在容器中重新创建 我想知道这样做是否是一个好习惯 是的 这是一个
  • 合并一个对(元组)列表?

    从链接对的列表中 我想将这些对组合成公共 ID 组 这样我就可以将 group ids 写回数据库 例如 UPDATE table SET group n WHERE id IN Example 1 2 3 4 1 5 6 3 7 8 be
  • Visual Studio Code 调试控制台中的 pydevd 警告

    我已经搜索了一段时间但找不到任何相关问题 当使用 Visual Studio Code 和 Python 扩展来调试大型元素时 计算表示或获取属性可能需要一些时间 在这些情况下 会出现如下警告 pydevd 警告 计算 DataFrame
  • 如何检查Docker中是否安装了python包?

    我使用Dockerfile成功构建了一个容器 但是 我的代码在容器中不起作用 如果我手动安装所有软件包 它确实有效 我假设我搞砸了一些导致 docker 没有正确安装软件包的事情 所以 我想检查Docker容器中是否安装了python包 最
  • Python 2.7从非默认目录打开多个文件(对于opencv)

    我在 64 位 win7 上使用 python 2 7 并拥有 opencv 2 4 x 当我写 cv2 imread pic 时 它会在我的默认 python 路径中打开 pic 即C Users Myname 但是我如何设法浏览不同的目
  • 在 Flask 中将配置文件作为字典读取

    在 instance app cfg 我已经配置 test test 在我的烧瓶文件 app py 中 with app open instance resource app cfg as f config f read print con
  • python下安装xgboost 32位msys失败

    尝试安装 xgboost 失败 Windows 和企业版版本为 Anaconda 2 1 0 64 位 我该如何继续 我一直在使用 R 似乎从 RStudio 在 R 中安装新包相当容易 但在间谍程序中则不然 因为我需要进入命令窗口来执行此
  • 如何在 matplotlib 图中禁用 xkcd?

    您可以通过以下方式打开 xkcd 风格 import matplotlib pyplot as plt plt xkcd 但如何禁用它呢 I try self fig clf 但这行不通 简而言之 要么使用 Valentin 提到的上下文管
  • 使用 Python 将 Json 转换为换行 Json 标准

    我有一个获取嵌套对象并删除所有嵌套的代码 使对象平坦 def flatten json y param y Unflated Json return Flated Json out def flatten x name if type x
  • 如何从张量流数据集迭代器返回同一批次两次?

    我正在转换一些旧代码以使用数据集 API 此代码使用feed dict将一批数据送入列车运行 实际上是三次 然后重新计算损失以供显示使用同一批 所以我需要一个迭代器来返回完全相同的批次两次 或多次 不幸的是 我似乎找不到一种使用张量流数据集
  • 调度算法,找到设定长度的所有非重叠区间

    我需要为我的管理应用程序实现一种算法 该算法将告诉我何时可以将任务分配给哪个用户 我实现了一个蛮力解决方案 它似乎有效 但我想知道是否有更有效的方法来做到这一点 为了简单起见 我重写了算法以对数字列表进行操作 而不是数据库查询等 下面我将尝
  • 当没有 main 函数时,为什么 sys.settrace 不触发?

    import sys def printer frame event arg print frame event arg return printer sys settrace printer x 1 sys settrace None 上
  • 捕获 subprocess.run() 的输入

    我在 Windows 上有一个交互式命令行 exe 文件 是由其他人编写的 当程序出现异常时 它会终止 并且我对程序的所有输入都会丢失 所以我正在编写一个 python 程序 它调用一个阻塞子进程subprocess run 并捕获所有输入
  • 如何将 pygame Surface 转换为 PIL 图像?

    我正在使用 PIL 来透视地变换屏幕的一部分 原始图像数据是一个 pygame Surface 需要转换为 PIL 图像 因此我发现了 pygame 的 tostring 函数就是为了这个目的而存在的 然而结果看起来很奇怪 见附图 这段代码

随机推荐

  • 如何在局域网中找到我的服务器?

    我有两个自己的 C 和 Java 应用程序 服务器和客户端 它既在一个局域网内 又可以通过指定的端口传输数据 我想让客户端可以找到服务器的IP 但怎么办呢 使用地址掩码枚举所有可能的 IP 坏主意 这会花费很多时间 可能存在某种方式 我可以
  • 在控制器中找不到名称空间内的 Ruby on Rails 模型

    我是 Rails 新手 无法解决这个问题 我有一个控制器 Admin Blog EntriesController 定义在app controllers admin blog entries controller rb 我有一个模型叫 Bl
  • 无法在 Ubuntu 22.04 操作系统上通过 vscode sftp 扩展连接到 AWS EC2 服务器

    我曾经连接 Linode 和 GCP 提供的远程服务器 并通过 Sftp 扩展使用 Visual Studio Code 一切正常 但是 使用相同的配置集 我无法连接到我的 Aws EC2 服务器 以下是sftp json 敏感信息已更改
  • 如何将多个属性传递到 Angular.js 属性指令中?

    我有一个属性指令限制如下 restrict A 我需要传入两个属性 一个数字和一个函数 回调 使用指令在指令中访问它们attrs object 如果指令是元素指令 则受限制 E 我可以这样
  • std::call_once 是无锁的吗?

    我想知道 std call once 锁是否已释放 There https codereview stackexchange com questions 117468 stdonce flag and stdcall once implem
  • C# SSL 安全套接字

    我有一个用 C 编写的 运行良好的通信器应用程序 现在我需要实现与服务器的安全连接 我尝试将 Socket 和 TcpClient 对象更改为 SslStream 但出现了一些错误 首先 我使用 makecert 生成了一个 cer 证书
  • 将方法作为参数传递与直接调用方法

    我在一些示例中看到了作为参数传递的方法 如果我可以从另一种方法调用一种方法 为什么我应该将方法作为参数传递 这个设计背后的目的是什么 从一种方法调用另一种方法 使用委托或将方法作为参数传递Action 将方法作为参数传递可用于防止依赖和耦合
  • 如何仅使用 CSS 来圆化我的 div 标签区域的角?

    我使用 div 标签来定义网页中的区域 我设置了所有明显的东西 如背景 大小 填充等 但它都是非常方形的 我该如何使用onlyCSS 圆角 这里有一个简单的 HTML 文档来演示如何仅通过 CSS 来实现它
  • 如何在没有浏览器检测的情况下识别“输入”事件中的错误行为?

    我将从问题开始 当特定浏览器的某个功能的实现有错误 并且您的 JavaScript 需要知道当前浏览器是否有该有错误的实现 以便它可以使用替代策略时 如何在不进行浏览器类型嗅探的情况下确定该实现是否有错误 这通常被认为是不好的 整个情况是这
  • 将纹理复制到纹理

    我已经完成了 2 个使用共享资源的程序 在 SlimDX 和 DirectX10 上运行 一个程序将在 3D 网格上显示共享纹理 第二个程序将加载图像作为纹理 到目前为止 每次从新图像更新纹理时 我都需要传递共享处理 现在 有没有一种方法可
  • Node.JS 验证 Google 身份验证令牌

    我正在尝试使用 Express JS 框架构建 Node JS REST 服务器 该框架为移动应用程序集成了 Google 身份验证 使用的 Node JS 版本是 0 12 7 我在验证从应用程序收到的 Google 令牌时遇到问题 因为
  • 在 Pandas 中将元组中的字符串拆分为列

    我有以下内容DataFrame where Track ID是行索引 我怎样才能分割字符串stats列分成5列数字 Track ID stats 14 0 0 00924175824176 0 41 0 742016492568 0 003
  • 重复命令 while true 或 x 次(相当于 while/for 循环)

    我想尽可能多地重复这个命令sometext在该领域note 表中的几行itemNotes可以有一个或多个sometext在该领域note UPDATE itemNotes SET note SUBSTR note 0 INSTR LOWER
  • 在php中计算数组[关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 如果我使用count 在我的 php 脚本中 值是zero还计数变量返回1 为什么 Why php count values always
  • 如何使用Python http.client PUT方法上传二进制/视频文件?

    我正在 Python 3 6 2 中使用 HTTP client 与 API 进行通信 为了上传文件 需要三个阶段的过程 我已经成功地使用 POST 方法进行了交谈 并且服务器按我的预期返回了数据 然而 需要上传实际文件的阶段是 PUT 方
  • Java 8方法参考使用示例

    我正在查看一个示例 该示例从与方法引用相关的当前目录中提取隐藏文件数组 如下所述 using 匿名内部类执行 File hiddenFiles new File listFiles new FileFilter public boolean
  • 在 Silverlight 5 中合并 ResourceDictonaries 中使用样式

    我的 app xaml 中有很多样式 它们都在 SL5 应用程序的页面中使用得很好 我想将这些样式移至多个资源词典 以使其更易于管理和使用 首先 我将样式复制到项目中 Styles ButtonStyles xaml 页面中的新资源字典中
  • 如何从 Dart/Flutter 中的泛型函数调用命名构造函数

    我希望能够从通用函数内部构造一个对象 我尝试了以下方法 abstract class Interface Interface func int x class Test implements Interface Test func int
  • 显示光标下的文本

    当鼠标指针放置在元素上时 我想显示一些文本 例如 如果您将光标放在对某个答案的赞成票上 它会显示 此答案很有用 您可以在下图中看到它 我什至不知道如何搜索这个 Add a title属性 https developer mozilla or
  • 无法使用服务帐户授权连接到自己的 GAE 端点 API

    我一直在拼命尝试成功授权对我使用 OAuth2 和服务帐户从 python 脚本运行的 Google App Engine GAE 项目的 API 访问 我创建了服务帐户 将服务帐户 ID 添加到 api 文件中允许的客户端 ID 将私钥从