14

我在 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 中交换令牌的方法。

4

2 回答 2

12

我看到你有"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 登录是分开的。)

于 2013-04-22T22:00:16.740 回答
0

我不知道这是什么时候引入的,但是如果您使用 OAuth2,则UserService.isUserAdmin()可以使用OAuthServiceFactory.getOAuthService().isUserAdmin(EMAIL_SCOPE)where EMAIL_SCOPEis " 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) {}
}

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

于 2015-12-11T14:32:41.667 回答