如何验证 google 端点中的 firebase 令牌?
How to verify firebase token in google endpoints?
我遵循了 firebase 身份验证的文档以及这方面的教程。
假设令牌将从 header 进入客户端,我创建了一个自定义身份验证器 class 并且我收到任务错误 The type TaskQueuePb.TaskQueueQueryAndOwnTasksResponse.Task is not generic; it cannot be parameterized with arguments <FirebaseToken>
但是,我没有看到任何其他导入,教程似乎也没有对此进行更多解释。
请参考以下代码:
package com.travelplannr.endpoint.firebase;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.http.HttpServletRequest;
import com.google.api.server.spi.ServiceException;
import com.google.api.server.spi.auth.common.User;
import com.google.api.server.spi.config.Authenticator;
import com.google.appengine.api.taskqueue.TaskQueuePb.TaskQueueQueryAndOwnTasksResponse.Task;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOptions;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseToken;
public class CustomAuthenticator implements Authenticator {
private static final Logger logger = Logger.getLogger(CustomAuthenticator.class.getName());
static {
try {
FileInputStream serviceAccount = new FileInputStream("path/to/serviceAccountKey.json");
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredentials(GoogleCredentials.fromStream(serviceAccount))
.setDatabaseUrl("https://<DATABASE_NAME>.firebaseio.com/")
.build();
FirebaseApp.initializeApp(options);
} catch (Exception e) {
logger.log(Level.SEVERE, e.toString(), e);
}
}
@Override
public User authenticate(HttpServletRequest httpServletRequest) {
//get token
final String authorizationHeader = httpServletRequest.getHeader("Authorization");
//verify
if(authorizationHeader != null) {
Task<FirebaseToken> task = FirebaseAuth.getInstance().verifyIdToken(authorizationHeader.replace("Bearer ", ""));
//wait for the task
try {
Tasks.await(task);
} catch (ExecutionException e) {
} catch (InterruptedException e) {
}
FirebaseToken firebaseToken = task.getResult();
User user = new User(firebaseToken.getUid(), firebaseToken.getEmail());
return user;
}
return null;
}
}
请帮忙!
提前致谢。
我认为这里有两个截然不同的问题,在同一行代码中。首先,您的作业中 return 类型的左手接收类型似乎不匹配。从 FirebaseAuth Java API reference 中可以看出,方法签名是:
FirebaseToken verifyIdToken(String token)
因此,verifyIdToken
return 是 FirebaseToken
,但您试图将其分配给 Task<FirebaseToken>
,这是一种不同的、不兼容的类型。其次,Task<FirebaseToken>
也是一个非法类型,因为这个 Task
class 不是泛型的,所以它根本不能被参数化。这是您从编译器看到的错误,但如果您完全放弃使用 Task
,那么该细节将变得无关紧要,因为它是不必要的:
FirebaseToken firebaseToken = FirebaseAuth.getInstance().verifyIdToken(authorizationHeader.replace("Bearer ", ""));
只需删除尝试使用 Task
和 Tasks.await()
的所有其他代码。
您似乎一直在混合和匹配有关如何进行此调用的同步和异步信息源。由于您编写的代码将立即等待异步任务完成,因此您可能应该坚持使用 API (verifyIdToken()
) 的同步版本,而不是尝试使用异步变体 (verifyIdTokenAsync()
),在尝试遵循示例时可能会造成一些混淆。
我遵循了 firebase 身份验证的文档以及这方面的教程。
假设令牌将从 header 进入客户端,我创建了一个自定义身份验证器 class 并且我收到任务错误 The type TaskQueuePb.TaskQueueQueryAndOwnTasksResponse.Task is not generic; it cannot be parameterized with arguments <FirebaseToken>
但是,我没有看到任何其他导入,教程似乎也没有对此进行更多解释。
请参考以下代码:
package com.travelplannr.endpoint.firebase;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.http.HttpServletRequest;
import com.google.api.server.spi.ServiceException;
import com.google.api.server.spi.auth.common.User;
import com.google.api.server.spi.config.Authenticator;
import com.google.appengine.api.taskqueue.TaskQueuePb.TaskQueueQueryAndOwnTasksResponse.Task;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOptions;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseToken;
public class CustomAuthenticator implements Authenticator {
private static final Logger logger = Logger.getLogger(CustomAuthenticator.class.getName());
static {
try {
FileInputStream serviceAccount = new FileInputStream("path/to/serviceAccountKey.json");
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredentials(GoogleCredentials.fromStream(serviceAccount))
.setDatabaseUrl("https://<DATABASE_NAME>.firebaseio.com/")
.build();
FirebaseApp.initializeApp(options);
} catch (Exception e) {
logger.log(Level.SEVERE, e.toString(), e);
}
}
@Override
public User authenticate(HttpServletRequest httpServletRequest) {
//get token
final String authorizationHeader = httpServletRequest.getHeader("Authorization");
//verify
if(authorizationHeader != null) {
Task<FirebaseToken> task = FirebaseAuth.getInstance().verifyIdToken(authorizationHeader.replace("Bearer ", ""));
//wait for the task
try {
Tasks.await(task);
} catch (ExecutionException e) {
} catch (InterruptedException e) {
}
FirebaseToken firebaseToken = task.getResult();
User user = new User(firebaseToken.getUid(), firebaseToken.getEmail());
return user;
}
return null;
}
}
请帮忙! 提前致谢。
我认为这里有两个截然不同的问题,在同一行代码中。首先,您的作业中 return 类型的左手接收类型似乎不匹配。从 FirebaseAuth Java API reference 中可以看出,方法签名是:
FirebaseToken verifyIdToken(String token)
因此,verifyIdToken
return 是 FirebaseToken
,但您试图将其分配给 Task<FirebaseToken>
,这是一种不同的、不兼容的类型。其次,Task<FirebaseToken>
也是一个非法类型,因为这个 Task
class 不是泛型的,所以它根本不能被参数化。这是您从编译器看到的错误,但如果您完全放弃使用 Task
,那么该细节将变得无关紧要,因为它是不必要的:
FirebaseToken firebaseToken = FirebaseAuth.getInstance().verifyIdToken(authorizationHeader.replace("Bearer ", ""));
只需删除尝试使用 Task
和 Tasks.await()
的所有其他代码。
您似乎一直在混合和匹配有关如何进行此调用的同步和异步信息源。由于您编写的代码将立即等待异步任务完成,因此您可能应该坚持使用 API (verifyIdToken()
) 的同步版本,而不是尝试使用异步变体 (verifyIdTokenAsync()
),在尝试遵循示例时可能会造成一些混淆。