首页 > 解决方案 > 使用令牌从本地运行的 Google Cloud 应用程序检索 Firebase 用户

问题描述

我正在开发一个用作端点 API 的 Java API,并且在生产中它在 Google Cloud Platform 上运行。通过将 Firebase 令牌作为 URL 的一部分传递来调用 API 方法,该令牌用于创建UserAPI 方法内部可用的对象:

@ApiMethod(path = "myPath/{tokenId}/doSomething", httpMethod = "get")
    public ResponseMessage ReturnSomething(@Named("tokenId") String tokenId, User user) throws UnauthorizedException, BadRequestException, InternalServerErrorException, FirebaseAuthException  
    {
        if (user == null)
        ...

在生产中,当从 Firebase 上的 Angular 应用程序调用 URL 时,该 URLuser将正确创建传递 URL 中的令牌。我不完全了解它User是如何从令牌创建的,我只知道它以某种方式“自动”发生,作为 Firebase 与 Google Cloud 集成的一部分。

我想在 Eclipse 内部使用Debug As > App Engine在本地调试 API。但是,当我这样做并从使用 Firebase 服务运行的本地 Angular 应用程序调用 API 时,令牌会正确传递给我本地运行的 API,但user始终是null.

@ApiMethod(path = "myPath/{tokenId}/doSomething", httpMethod = "get")
    public ResponseMessage ReturnSomething(@Named("tokenId") String tokenId, User user) throws UnauthorizedException, BadRequestException, InternalServerErrorException, FirebaseAuthException  
    {
        if (user == null)
        // this is always null

我怀疑这是我在本地运行的 Java API 正确验证 Firebase 的问题。我看过这个指南,它建议GOOGLE_APPLICATION_CREDENTIALS应该将 Windows 上的属性设置为 App Engine 默认服务帐户的 JSON 密钥的路径,这是确保向 Google Cloud 授予本地访问权限的正常方法(以及大概是 Firebase)资源。

我已经明确添加了这个(无论如何我已经gcloud auth application-default login使用命令行运行了)但是它仍然无法正常工作。我只是得到nulluser,没有迹象表明发生了什么。我不想以编程方式进行身份验证,因为这意味着在调试期间更改 API 代码以进行不同的身份验证。User作为 App Engine 在本地调试时如何检索?

更新

我意识到虽然tokenIdURL 中存在 ,但在调用 API 时出现以下错误:

WARNING: Authentication failed: com.google.api.auth.UnauthenticatedException: No auth token is contained in the HTTP request

下面tokenId代码中的值是有效值,所以我不确定为什么会收到此消息:

@ApiMethod(path = "myPath/{tokenId}/doSomething", httpMethod = "get")
    public ResponseMessage ReturnSomething(@Named("tokenId") String tokenId, User user)

标签: javafirebasegoogle-cloud-platformfirebase-authentication

解决方案


我发现这实际上是Angular 中用于支持对 Java API 的经过身份验证的 HTTP 请求的Auth0库的问题。每当从 Angular 应用程序调用Angular 时,Auth0 库用于将身份验证令牌注入到Bearer请求标头中。http.get的创建User取决于HTTP 标头中存在的此属性,其值设置为身份验证令牌的值。

我通过更改此库的配置来解决此问题。我需要将localhost运行 API 的端口 (8080) 临时列入白名单,以允许 Auth0 在有请求时将令牌注入 HTTP 标头localhost:8080

const jwtConf: JwtModuleOptions = {
  config: {
    tokenGetter: getToken,
    whitelistedDomains: ['localhost:8080']
  }
};

推荐阅读