Google Cloud Endpoints + Firebase Auth:method_info未设置

时间:2017-03-12 15:08:43

标签: firebase firebase-authentication google-cloud-endpoints google-cloud-endpoints-v2

所以我正在运行Google提供的示例代码:

package com.neat.backend;
/**
 * An endpoint class we are exposing
 */
@Api(
        name = "myApi",
        version = "v1",
        namespace = @ApiNamespace(
                ownerDomain = "backend.neat.com",
                ownerName = "backend.neat.com",
                packagePath = ""
        ),
        issuers = {
        @ApiIssuer(
                name = "firebase",
                issuer = "https://securetoken.google.com/" + PROJECT_ID,
                jwksUri = "https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com")
})
public class MyEndpoint {

    @ApiMethod(
            path = "firebase_user",
            httpMethod = ApiMethod.HttpMethod.GET,
            authenticators = {EspAuthenticator.class},
            issuerAudiences = {@ApiIssuerAudience(name = "firebase", audiences = {PROJECT_ID})}
    )
    public Email getUserEmailFirebase(User user) throws UnauthorizedException {
        if (user == null) {
            throw new UnauthorizedException("Invalid credentials");
        }

        Email response = new Email(user.getEmail());
        return response;
    }

}

我从Android客户端获取Firebase令牌并尝试通过以下方式将其发送到后端:

curl -H "Authorization: Bearer FIREBASE_JWT_TOKEN" \
     -X GET \
     http://localhost:8080/_ah/api/echo/v1/firebase_user

我在日志中看到的错误如下:

[INFO] java.lang.IllegalStateException: method_info is not set in the request
[INFO]  at com.google.api.server.spi.auth.EspAuthenticator.authenticate(EspAuthenticator.java:67)
[INFO]  at com.google.api.server.spi.request.Auth.authenticate(Auth.java:100)
[INFO]  at com.google.api.server.spi.request.ServletRequestParamReader.getUser(ServletRequestParamReader.java:191)
[INFO]  at com.google.api.server.spi.request.ServletRequestParamReader.deserializeParams(ServletRequestParamReader.java:136)
[INFO]  at com.google.api.server.spi.request.RestServletRequestParamReader.read(RestServletRequestParamReader.java:123)
[INFO]  at com.google.api.server.spi.SystemService.invokeServiceMethod(SystemService.java:350)
[INFO]  at com.google.api.server.spi.handlers.EndpointsMethodHandler$RestHandler.handle(EndpointsMethodHandler.java:114)
[INFO]  at com.google.api.server.spi.handlers.EndpointsMethodHandler$RestHandler.handle(EndpointsMethodHandler.java:102)
[INFO]  at com.google.api.server.spi.dispatcher.PathDispatcher.dispatch(PathDispatcher.java:49)
[INFO]  at com.google.api.server.spi.EndpointsServlet.service(EndpointsServlet.java:71)
[INFO]  at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

我尝试将完全相同的代码部署到App Engine,它运行良好。我试过调试EspAuthenticator,似乎期望Servlet过滤器在请求中注入一些属性。

4 个答案:

答案 0 :(得分:4)

我花了一些时间和一些调试才意识到应该注入method_info的过滤器没有被触发。

我可以通过修改web.xml中的映射来添加以下调度程序标记来修复它:

<filter-mapping>
    <filter-name>endpoints-api-configuration</filter-name>
    <servlet-name>EndpointsServlet</servlet-name>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>FORWARD</dispatcher>
</filter-mapping>

答案 1 :(得分:1)

生成并部署OpenAPI配置文件

$ mvn clean package endpoints-framework:openApiDocs -DskipTests
$ gcloud endpoints services deploy target/openapi-docs/openapi.json
$ mvn appengine:run 

答案 2 :(得分:0)

我收到了相同的错误消息,并最终将其跟踪为在我的API未指定的URL中发出跟踪/的请求。尾部斜杠只会导致提供授权令牌的调用出错。

显然ControlFilter(因此也GoogleAppEngineControlFilter)没有将其识别为有效端点,因此不会将method_info附加到请求中。但后来EndpointsServlet认为 有效并尝试在没有所有必要信息的情况下进行身份验证!

修复很简单:从我的请求中的URL中删除尾部斜杠。然而,追踪问题并非如此!我觉得这不是你的问题,但也许这个答案可以帮助别人。

答案 3 :(得分:0)

@Kevendra的答案强调指出,如果openapi.json文件缺少对端点API方法的引用,则可能导致此问题。 Firebase可能正在使用它来引用和发现API方法。

从Google OpenAPI概述:

  

OpenAPI文档的基本结构:

     

OpenAPI文档描述   REST API的表面,并定义以下信息:

     

API的名称和描述。各个端点(路径)   在API中。呼叫者如何进行身份验证。

请按照以下步骤重新生成并部署openapi.json文件:


生成:

$ mvn clean package endpoints-framework:openApiDocs -DskipTests

部署:

(作为预防措施,您可以首先验证以下命令返回的项目ID,以确保未在错误的项目中创建服务-gcloud config list project

  $ gcloud endpoints services deploy target/openapi-docs/openapi.json

从其生成的位置部署openapi.json文件(在上面的“生成”步骤中)。请参阅Deploying the OpenAPI document

上的Google文档