【问题标题】:How do I use the Google API Explorer to test my own App Engine Endpoints using OAuth?如何使用 Google API Explorer 通过 OAuth 测试我自己的 App Engine Endpoints?
【发布时间】:2013-04-14 12:08:36
【问题描述】:

我在 App Engine 上部署了一个 Endpoints API。我使用 Google API Explorer 向不需要登录的 API 方法发出请求没有问题。我使用的 URL 是:

https://developers.google.com/apis-explorer/?base=https://[MY_APP_ID].appspot.com/_ah/api

我卡住的地方是调用需要用户登录的 API 方法,例如这个:

@ApiMethod(name = "config.get",
        clientIds = {"[MY_CLIENT_ID].apps.googleusercontent.com", "com.google.api.server.spi.Constant.API_EXPLORER_CLIENT_ID"},
        audiences = {"[MY_APP_ID].appspot.com"},
        scopes = {"https://www.googleapis.com/auth/userinfo.email"})
public Config getConfig(User user) throws OAuthRequestException {
    log.fine("user: " + user);

    if (user == null) {
        throw new OAuthRequestException("You must be logged in in order to get config.");
    }

    if (!userService.isUserAdmin()) {
        throw new OAuthRequestException("You must be an App Engine admin in order to get config.");
    }
    ...

在 API Explorer 右上角有一个开关,单击该开关后,我可以指定范围和授权。我只检查了 userinfo.email 范围。这没什么区别。我从电话中得到的回应是:

503 Service Unavailable

- Show headers -

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "backendError",
    "message": "java.lang.IllegalStateException: The current user is not logged in."
   }
  ],
  "code": 503,
  "message": "java.lang.IllegalStateException: The current user is not logged in."
 }
}

当 Endpoints 处于 Trusted Tester 阶段时,我记得在 OAuth2 Playground 中有一个手动步骤来获取 ID 令牌而不是访问令牌或类似的东西。如果仍然需要这样做,那么现在 Endpoints 文档中似乎已经没有提及这一点,我现在也看到了在 API Explorer 中交换令牌的方法。

【问题讨论】:

标签: google-app-engine oauth-2.0 google-cloud-endpoints


【解决方案1】:

我看到你有 "com.google.api.server.spi.Constant.API_EXPLORER_CLIENT_ID" 引号。如果这不是您对 Stack Overflow 的转录中的拼写错误,那就是个问题。该值已经是一个字符串,因此您只需将文本 com.google.api.server.spi.Constant.API_EXPLORER_CLIENT_ID(不是实际的客户端 ID)作为白名单范围传递。那是行不通的。试试这个:

@ApiMethod(name = "config.get",
        clientIds = {"[MY_CLIENT_ID].apps.googleusercontent.com", com.google.api.server.spi.Constant.API_EXPLORER_CLIENT_ID},
        audiences = {"[MY_APP_ID].appspot.com"},
        scopes = {"https://www.googleapis.com/auth/userinfo.email"})

编辑isUserAdmin 在 Endpoints 中不受支持,可能是错误的次要原因。我建议在提供的 User 对象上提交支持此方法的功能请求(我们可能不会为用户服务本身提供支持,因此它与 OAuth 登录是分开的。)

【讨论】:

  • 好发现!已修复该问题并重新部署,但似乎没有任何区别。肯定坏了,但也有其他东西坏了。
  • 我无法使用几乎相同的示例代码重现此问题。您最初问题中的代码是您现在使用的吗?奇怪的是你得到的是 503 而不是 401,这是 OAuthRequestException 应该映射到的(我自己测试时看到了 401)。
  • 这绝对是部署的。如果我在没有登录的情况下点击此方法,我会得到像你一样的 401。如果我然后使用 API Explorer 上的 OAuth2 按钮登录并再次点击它,我会得到 503。但是,如果我点击 another Endpoints 方法,我会得到需要用户登录但不包括对 App Engine UserService 的任何使用,它工作正常。我不能在 Endpoints 中使用 UserService.isUserAdmin() 之类的东西吗?大概这些东西仍然基于 HTTP 会话而不是 OAuth 访问令牌?
  • 哦,哇,我瞎了。不,您不能在 Endpoints 中使用 isUserAdmin。如果您想要类似管理员的功能,您需要使用自己的 ACL 来管理它。
  • 好的。我想这是有道理的。不过对于文档来说可能是一个不错的选择。感谢您的帮助。
【解决方案2】:

我不知道这是什么时候引入的,但是如果您使用 OAuth2,而不是 UserService.isUserAdmin(),您可以使用 OAuthServiceFactory.getOAuthService().isUserAdmin(EMAIL_SCOPE),其中 EMAIL_SCOPE 是“https://www.googleapis.com/auth/userinfo.email”。

这使得使用旧的 OpenId 或 OAUth2 变得容易:

boolean isAdmin = false;
try {
  isAdmin = userService.isUserAdmin());
} catch (IllegalStateException e1) {
  try {
    isAdmin = OAuthServiceFactory.getOAuthService().isUserAdmin(EMAIL_SCOPE);
  } catch (Exception e2) {}
}

最初的问题是几年前提出的,但也许这对其他人有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多