2

我正在尝试向我的python云函数添加授权。我在GCP项目中创建了一个服务帐户并生成了密钥。调用云函数的测试客户端代码(不在GCP中)如下所示:

从google.oauth2导入service_account从google.auth.transport.requests导入AuthorizedSessionSERVICE_ACCOUNT_FILE='<my_project_key_FILE>.json'credentials=服务帐户。凭据.from_service_account_file(service_account_file,scopes=['https://www.googleapis.com/auth/userinfo.email'])authed_session=授权会话(凭据)response=authd_session.get('http://<my_project>.cloudfunctions.net/authValidation')

我知道这段代码正确地从谷歌获得了JWT承载令牌,并被添加到我的云函数调用中的Authorization头中。我只是很难在云函数中验证该令牌。该代码的相关部分如下所示:

从google.oauth2导入id_token来自google.auth.transport导入请求def hello_world(请求):#来自https://developers.google.com/identity/sign-in/web/backend-auth#使用-a-google-api-客户端库idinfo=id_token.verify_oauth2_token(request.headers.get('Authorization')[7:]),个请求。请求())

我知道id标记是正确的,因为手动验证(使用https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=xxx)返回我期望的结果。

我得到的错误日志堆栈跟踪是:

回溯(最近一次调用):run_http_function中的文件“/env/local/lib/python3.7/site-packages/google/cloud/functions/worker.py”,第346行结果=_function_handler.invoke_user_function(flask.request)invoke_user_function中的文件“/env/local/lib/python3.7/site-packages/google/cloud/functions/worker.py”,第217行返回call_user_function(请求或事件)call_user_function中的文件“/env/local/lib/python3.7/site-packages/google/cloud/functions/worker.py”,第210行返回自我_用户功能(请求或事件)hello_world中的文件“/user_code/main.py”,第17行idinfo=id_token.verify_oauth2_token(request.headers.get('Authorization')[7:],请求。请求())文件“/env/local/lib/python3.7/site-packages/google/oauth2/id_token.py”,第141行,位于verify_oauth2_token中certs_url=_GOOGLE_OAUTH2_certs_url)文件“/env/local/lib/python3.7/site-packages/google/oauth2/id_token.py”,第122行,位于verify_token中return jwt.decode(id_token,certs=certs,audience=audience)文件“/env/local/lib/python3.7/site-packages/google/auth/jwt.py”,第219行,解码中标头,有效载荷,signed_section,signature=_unverified_decode(标记)文件“/env/local/lib/python3.7/site-packages/google/auth/jwt.py”,第139行,在_unverified_decode中header=_decode_jwt_segment(编码头)文件“/env/local/lib/python3.7/site-packages/google/auth/jwt.py”,第112行,位于_decode_jwt_segment中六、raise_from(new_exc,caught_exc)raise_from中的文件“<string>”,第3行ValueError:无法分析段:b'\xc9\xad\xbd'

我在这里错过了什么?谢谢

  • 前10个字符来自哪里request.headers.get(“授权”)[7:]? 问题看起来是您没有正确获取令牌,解码失败。 评论 2019年4月20日2:16
  • Authorization标头为轴承ya29.c.EljxBqdHSeW1IQc。。。。同样,如果我取这个值(减去“Bearer”指示符)并将其放入googleapis.com/oauth2/v1/tokeninfo?access_token=xxx它正确地验证了它,所以我不确定“离线”验证器代码缺少了什么。 评论 2019年4月20日12:52
  • 你能解决这个问题吗?我也遇到了这个问题。
    – 胡萝卜
    评论 2020年7月9日22:30

2个答案2

重置为默认值
0

通过设置谷歌_APPLICATION_CREDENTIAL在本地系统中,客户端将在该服务帐户的上下文中运行,而无需担心身份验证。您不需要对密钥文件的路径进行编码。

也适用于部署云功能并在本地测试它。部署云函数时,它将作为AppEngine默认服务帐户或使用--service-account参数指定的服务帐户运行:https://cloud.google.com/sdk/gcloud/reference/functions/deploy

参考文献:https://cloud.google.com/docs/authentication/production网站

这样,您就不需要将密钥推送到服务器或在git中担心它,并且在本地和远程运行时也不需要进行任何代码更改。

  • 错过了这是一个测试客户端,但同样的原则适用,但看看这个测试客户端:cloud.google.com/functions/docs/bestpractices/…这是存储触发函数,但也有pubsub的示例。
    – 迈克尔
    评论 2019年4月19日22:43
  • 我认为更重要的问题是,为什么使用云功能来接收必须经过身份验证的流量?除了CORS之外,Google没有提供任何关于验证http功能客户端身份的文档,而他们提供了其他一些易于使用的工具,这些工具可以满足要求,例如Pub/Sub和CloudEndpoint,其中auth与get_user或配置一样简单。
    – 迈克尔
    评论 2019年4月21日20:44
  • 我不同意,编程就是解决问题,通常有很多方法可以解决问题。在本例中,我提供了一个不同的解决方案,即云端点或Pub/Sub,两者都可以解决手头的问题。现在,如果您想回答他关于如何在http函数中验证access_token而不是批评我的问题,请继续。
    – 迈克尔
    评论 2019年4月22日21:10
0

确保将字符串传递给id_token.verify_oauth2_token()开头没有“承载者”。

你的答案

单击“发布您的答案”,表示您同意我们的服务条款并确认您已阅读我们的隐私政策.

不是你想要的答案吗?浏览标记的其他问题问你自己的问题.