有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Google Cloud Endpoints API方法仅在删除用户参数时成功调用

我在一个应用程序中有一个API方法(用Java编写),它被部署为一组在Google云上运行的端点。该API使用OpenAPI并使用ESP(Extensible Service Proxy)来中继来自该API的请求并调解任何身份验证

我创建了一个新的API方法,如下所示:

@ApiMethod(path="my/path/{param}",httpMethod = "get")
public Object[] GetSomethingUsingFirebaseAuthentication(@Named("param") String param) throws UnauthorizedException,BadRequestException,NotFoundException
{
     // implementation
}

我可以使用debug As>;在本地运行时进行调试;当我使用'debug as>;应用程序引擎'。我使用的邮递员设置如下所示(注意,我在授权头的“承载者”中传递身份验证令牌):

enter image description here

该方法被成功调用并返回成功响应,这证明我正确调用了该方法并且该方法有效。如果我随后添加一个参数以接受Firebase用户,则该方法将失败:

@ApiMethod(path="my/path/{param}",httpMethod = "get")
public Object[] GetSomethingUsingFirebaseAuthentication(@Named("param") String param, User user) throws UnauthorizedException,BadRequestException,NotFoundException
{
     // some auth code based on the Firebase 'user'
}

现在,我已经添加了User参数,调用该方法的方式与使用Postman之前完全相同,现在我得到一个http 503错误:

method_info is not set

以下是http JSON响应:

{
    "error": {
        "errors": [
            {
                "domain": "global",
                "reason": "backendError",
                "message": "backend error"
            }
        ],
        "code": 503,
        "message": "backend error"
    }
}

问题与此非常相似:

Google Cloud Endpoints + Firebase Auth: method_info is not set

不过,我的问题的不同之处在于,当我将端点API部署到生产环境时,仍然会遇到问题

我还有其他非常类似的API方法,它们接受Firebase用户,并且都在生产中工作。当我在本地调试它时,其中一个类似的API方法也可以工作,所以我不需要更改配置

上述问题的公认答案(修改web.xml中的映射以使过滤器工作,该过滤器应该注入方法_info)对我不起作用。在任何情况下,这都是对我自己问题的攻击,因为其他API方法似乎在本地和生产中工作


关于这应该如何工作的一些解释-ESP(可扩展服务代理)是Google云的东西,是端点API的包装器,它可以使用Firebase令牌为用户调解身份验证(在我的例子中,该令牌在授权头的承载中传递)。然后,应将经过身份验证的Firebase用户作为user参数传入


这是完整的堆栈跟踪

WARNING: exception occurred while invoking backend method
java.lang.IllegalStateException: method_info is not set in the request
    at com.google.api.server.spi.auth.EspAuthenticator.authenticate(EspAuthenticator.java:67)
    at com.google.api.server.spi.request.Auth.authenticate(Auth.java:101)
    at com.google.api.server.spi.request.ServletRequestParamReader.getUser(ServletRequestParamReader.java:205)
    at com.google.api.server.spi.request.ServletRequestParamReader.deserializeParams(ServletRequestParamReader.java:141)
    at com.google.api.server.spi.request.RestServletRequestParamReader.read(RestServletRequestParamReader.java:135)
    at com.google.api.server.spi.SystemService.invokeServiceMethod(SystemService.java:349)
    at com.google.api.server.spi.handlers.EndpointsMethodHandler$RestHandler.handle(EndpointsMethodHandler.java:119)
    at com.google.api.server.spi.handlers.EndpointsMethodHandler$RestHandler.handle(EndpointsMethodHandler.java:102)
    at com.google.api.server.spi.dispatcher.PathDispatcher.dispatch(PathDispatcher.java:50)
    at com.google.api.server.spi.EndpointsServlet.service(EndpointsServlet.java:72)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at com.google.inject.servlet.ServletDefinition.doServiceImpl(ServletDefinition.java:287)
    at com.google.inject.servlet.ServletDefinition.doService(ServletDefinition.java:277)
    at com.google.inject.servlet.ServletDefinition.service(ServletDefinition.java:182)
    at com.google.inject.servlet.ManagedServletPipeline.service(ManagedServletPipeline.java:91)
    at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:85)
    at com.google.api.control.ControlFilter.doFilter(ControlFilter.java:229)
    at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
    at com.google.api.control.ConfigFilter.doFilter(ConfigFilter.java:120)
    at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
    at com.google.inject.servlet.ManagedFilterPipeline.dispatch(ManagedFilterPipeline.java:119)
    at com.google.inject.servlet.GuiceFilter$1.call(GuiceFilter.java:133)
    at com.google.inject.servlet.GuiceFilter$1.call(GuiceFilter.java:130)
    at com.google.inject.servlet.GuiceFilter$Context.call(GuiceFilter.java:203)
    at com.google.inject.servlet.GuiceFilter.doFilter(GuiceFilter.java:130)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642)
    at com.google.appengine.tools.development.ResponseRewriterFilter.doFilter(ResponseRewriterFilter.java:134)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642)
    at com.google.appengine.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:34)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642)
    at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:63)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642)
    at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:48)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642)
    at com.google.appengine.tools.development.jetty9.StaticFileFilter.doFilter(StaticFileFilter.java:123)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642)
    at com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectRequest(DevAppServerModulesFilter.java:366)
    at com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectModuleRequest(DevAppServerModulesFilter.java:349)
    at com.google.appengine.tools.development.DevAppServerModulesFilter.doFilter(DevAppServerModulesFilter.java:116)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642)
    at com.google.appengine.tools.development.DevAppServerRequestLogFilter.doFilter(DevAppServerRequestLogFilter.java:44)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1634)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:533)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:146)
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:524)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:257)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1595)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:255)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1340)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:203)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:473)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1564)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:201)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1242)
    at com.google.appengine.tools.development.jetty9.DevAppEngineWebAppContext.doScope(DevAppEngineWebAppContext.java:94)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:144)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
    at com.google.appengine.tools.development.jetty9.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:595)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
    at org.eclipse.jetty.server.Server.handle(Server.java:503)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:364)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:260)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:305)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
    at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:118)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:765)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:683)
    at java.lang.Thread.run(Unknown Source)

调试时在Eclipse中得到的唯一警告是

WARNING: No file found for: /_ah/start

有什么想法可以导致这个问题,或者我可以看看什么?对于如何调试或诊断该问题的任何建议,我都非常感谢:)


共 (1) 个答案

  1. # 1 楼答案

    需要重新生成端点API的OpenAPI文件,并将其部署到生产Google云端点,以便在本地调试时让auth工作

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

    endpoints API的本地版本引用了仅用于生产的Firebase auth服务,而Firebase auth服务必须从生产endpoints API中的openapi.json获取其端点API引用

    从Google OpenAPI Overview上:

    An OpenAPI document describes the surface of your REST API, and defines information such as:

    The name and description of the API. The individual endpoints (paths) in the API. How the callers are authenticated.