将Firebase身份验证与Google应用引擎云端端点集成

9
有人可以提供一些示例代码来说明如何在Google Cloud端点中验证Firebase令牌吗?最近提出的问题并没有完全澄清(How to integrate firebase authentication with google app engine endpoints)。
在端点中进行Google身份验证是通过向端点添加User参数自动完成的。可以使用Facebook Graph API在云端点中验证Facebook令牌,就像这样:
    @ApiMethod(name = "endpoint.addUser", httpMethod = HttpMethod.POST)
        public ResultObject addUser(HttpServletRequest request, User pUser) throws OAuthRequestException {
    String token = request.getHeader("Authorization");
    String graphUrl  = "https://graph.facebook.com/v2.6/me?fields=id,name,email&access_token=" + token;

    URL u = new URL(g);
    URLConnection c = u.openConnection();
    BufferedReader in = new BufferedReader(new InputStreamReader(c.getInputStream()));
    String inputLine;
    StringBuffer b = new StringBuffer();
    while ((inputLine = in.readLine()) != null){
             b.append(inputLine + "\n");            
    }
    in.close();
    graph = b.toString();
    JSONObject json = new JSONObject(graph);

    facebookId = json.getString("id");
    email = json.getString("email");
    //...
}

验证 Firebase Token 和 Facebook Token 一样简单吗?从 Firebase Token 中获取电子邮件地址是否可行?


我无法准确回答有关Firebase的问题,但我想说这不是集成认证的正确方式。你应该实现com.google.api.server.spi.config.Authenticator,然后在注解中指定这个Authenticator。我相信Firebase认证令牌是JWT,所以不需要发送请求来验证它们。 - saiyr
关于 Firebase,我想要验证令牌的原因是我已经有一个正在运行的应用引擎端点。现在我想在客户端中使用 Firebase Auth 并对云端端点进行身份验证。我现在不想迁移到 Firebase 实时数据库。 - SmilingM
我认为我在这个链接下找到了解决问题的方法:https://firebase.google.com/docs/auth/server/verify-id-tokens - SmilingM
1
@SmilingM 谢谢,这对我也是一个问题。您在最后一条评论中发布的链接显示了如何验证 Firebase 令牌,但不清楚如何将其与 Google Cloud Endpoint 的 User 参数配合使用。您能否在回答您的问题时进行解释?谢谢。 - aez
如果您找到了解决问题的方法,请考虑发布自我回答,以便社区受益。 - Adam
显示剩余3条评论
2个回答

2
据我理解文档,似乎您需要将用户令牌添加到请求中,例如作为标头。然后,您需要使用Firebase admin sdk验证此令牌,这样您就可以获得用户ID。
@ApiMethod(name = "someApiCall", httpMethod = ApiMethod.HttpMethod.POST)
public YourResponse someApiCall(YourRequestObject body, HttpServletRequest httpRequest) {
    String userToken = httpRequest.getHeader("USER_TOKEN_HEADER");

    Task<FirebaseToken> authTask = FirebaseAuth.getInstance().verifyIdToken(userToken)
        .addOnSuccessListener(new OnSuccessListener<FirebaseToken>() {
          @Override
          public void onSuccess(FirebaseToken firebaseToken) {
          }
        });

    try {
      Tasks.await(authTask);
    } catch (ExecutionException e) {
    } catch (InterruptedException e) {
    }

    FirebaseToken result = authTask.getResult();
    String userId = result.getUid();

    return new YourResponse();
}

我基于以下代码:

https://firebase.google.com/docs/auth/admin/verify-id-tokens

如何使用Firebase令牌验证保护我的Google Cloud Endpoints API?

1
你可以使用一个 CustomAuthenticator:

public class CustomAuthenticator implements Authenticator {
    private static final Logger LOG = Logger.getLogger(CustomAuthenticator.class.getName());
    private static final String COOKIE_FIREBASE_TOKEN = "firebase_token";

    static {
        LOG.info("CustomAuthenticator: initializing");
        InputStream serviceAccountResourceStream = CustomAuthenticator.class.getResourceAsStream("/serviceAccountKey.json");
        FirebaseOptions options = new FirebaseOptions.Builder()
                .setServiceAccount(serviceAccountResourceStream)
                .build();

        FirebaseApp.initializeApp(options);
        LOG.info("CustomAuthenticator: initialized");
    }

    @Override
    public User authenticate(HttpServletRequest httpServletRequest) {
        User user = null;
        if (httpServletRequest.getCookies() != null) {
            for (Cookie cookie : httpServletRequest.getCookies()) {
                if (cookie.getName().equals(COOKIE_FIREBASE_TOKEN)) {
                    FirebaseToken firebaseToken = FirebaseAuth.getInstance().verifyIdToken(cookie.getValue()).getResult();
                    user = new User(firebaseToken.getUid(), firebaseToken.getEmail());
                }
            }
        }
        return user;
    }
}

在您的API实现中,不要忘记启用自定义认证器:
@Api(name = "exampleWithAuth",
        version = "v1",
        ...
        auth = @ApiAuth(allowCookieAuth = AnnotationBoolean.TRUE), // This is needed to process your cookie for the token
        authenticators = {CustomAuthenticator.class} // Declare your custom authenticator
)
public class ExampleWithAuthEndpoint {

    @ApiMethod(httpMethod = "GET", path = "example")
    public Example getExample(User user /* Add User to enable API authentication */) {
        if (user != null) {
            // Do something
        }
        return null;
    }
}

现在当您调用API时,只需将cookie firebase_token 添加到您的请求中即可。
我希望这可以帮助您。

嘿,Nico,这种方法会不会让我们的API变慢,因为我们要再进行一次额外的调用? - Ajeet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接