我尝试按照以下方式通过后端服务器验证Google ID令牌:
https://developers.google.com/identity/sign-in/android/backend-auth
这些令牌最初是由android应用检索的,然后通过尝试验证的套接字传递给后端登录服务器。就目前情况而言,我正在导入的GoogleIdTokenVerifier代码在运行时抛出错误。
ServerThread.java:
GoogleIdToken idToken = GoogleAuthenticator.authenticateToken(tokenJson.getToken());
GoogleAuthenticator.java:
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Collections;
import java.util.Properties;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.extensions.appengine.http.UrlFetchTransport;
public class GoogleAuthenticator {
public GoogleAuthenticator(){
}
public static Properties prop;
public static GoogleIdToken authenticateToken(String inputToken) throws IOException{
final JacksonFactory jacksonFactory = new JacksonFactory();
prop = new Properties();
prop.load(GoogleAuthenticator.class.getClassLoader().getResourceAsStream("config.properties"));
GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(UrlFetchTransport.getDefaultInstance(), jacksonFactory)
// Specify the CLIENT_ID of the app that accesses the backend:
.setAudience(Collections.singletonList(prop.getProperty("google.web.client.id")))
// Or, if multiple clients access the backend:
//.setAudience(Arrays.asList(CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3))
.build();
GoogleIdToken idToken;
try {
idToken = verifier.verify(inputToken);
return idToken;
} catch (GeneralSecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
}
pom.xml
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client</artifactId>
<version>1.25.0</version>
</dependency>
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client-appengine</artifactId>
<version>1.25.0</version>
</dependency>
我目前看到以下堆栈跟踪:
Exception in thread "Thread-0" java.lang.NoClassDefFoundError: com/google/appengine/api/urlfetch/HTTPMethod
at com.google.api.client.extensions.appengine.http.UrlFetchTransport.buildRequest(UrlFetchTransport.java:118)
at com.google.api.client.extensions.appengine.http.UrlFetchTransport.buildRequest(UrlFetchTransport.java:50)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:872)
at com.google.api.client.googleapis.auth.oauth2.GooglePublicKeysManager.refresh(GooglePublicKeysManager.java:172)
at com.google.api.client.googleapis.auth.oauth2.GooglePublicKeysManager.getPublicKeys(GooglePublicKeysManager.java:140)
at com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier.verify(GoogleIdTokenVerifier.java:174)
at com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier.verify(GoogleIdTokenVerifier.java:192)
at com.omarhegazi.login.GoogleAuthenticator.authenticateToken(GoogleAuthenticator.java:40)
at com.omarhegazi.login.ServerThread.run(ServerThread.java:45)
在依赖关系中似乎没有可用的HTTPMethod类。有什么想法吗?
更新1:
在下面添加appengine依赖项已经取得了一些进展。我现在有以下堆栈跟踪错误:
Exception in thread "Thread-0" com.google.apphosting.api.ApiProxy$CallNotFoundException: The API package 'urlfetch' or call 'Fetch()' was not found.
at com.google.apphosting.api.ApiProxy.makeSyncCall(ApiProxy.java:98)
at com.google.appengine.api.urlfetch.URLFetchServiceImpl.fetch(URLFetchServiceImpl.java:37)
at com.google.api.client.extensions.appengine.http.UrlFetchRequest.execute(UrlFetchRequest.java:74)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:981)
at com.google.api.client.googleapis.auth.oauth2.GooglePublicKeysManager.refresh(GooglePublicKeysManager.java:172)
at com.google.api.client.googleapis.auth.oauth2.GooglePublicKeysManager.getPublicKeys(GooglePublicKeysManager.java:140)
at com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier.verify(GoogleIdTokenVerifier.java:174)
at com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier.verify(GoogleIdTokenVerifier.java:192)
at com.omarhegazi.login.GoogleAuthenticator.authenticateToken(GoogleAuthenticator.java:40)
at com.omarhegazi.login.ServerThread.run(ServerThread.java:45)
这是使用v1.6.1
我还尝试使用v1.9.70,结果如下:
Exception in thread "Thread-0" com.google.apphosting.api.ApiProxy$CallNotFoundException: Can't make API call urlfetch.Fetch in a thread that is neither the original request thread nor a thread created by ThreadManager
at com.google.apphosting.api.ApiProxy$CallNotFoundException.foreignThread(ApiProxy.java:800)
at com.google.apphosting.api.ApiProxy.makeSyncCall(ApiProxy.java:112)
at com.google.appengine.api.urlfetch.URLFetchServiceImpl.fetch(URLFetchServiceImpl.java:40)
at com.google.api.client.extensions.appengine.http.UrlFetchRequest.execute(UrlFetchRequest.java:74)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:981)
at com.google.api.client.googleapis.auth.oauth2.GooglePublicKeysManager.refresh(GooglePublicKeysManager.java:172)
at com.google.api.client.googleapis.auth.oauth2.GooglePublicKeysManager.getPublicKeys(GooglePublicKeysManager.java:140)
at com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier.verify(GoogleIdTokenVerifier.java:174)
at com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier.verify(GoogleIdTokenVerifier.java:192)
at com.omarhegazi.login.GoogleAuthenticator.authenticateToken(GoogleAuthenticator.java:40)
at com.omarhegazi.login.ServerThread.run(ServerThread.java:45)
貌似fetch软件包在1.6.1以后才包含,但存在一些与API调用线程有关的问题。
答案 0 :(得分:1)
尝试在您的appengine
中包含pom.xml
依赖项:
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-api-1.0-sdk</artifactId>
<version>1.6.1</version> <!-- Check your version -->
</dependency>
答案 1 :(得分:0)
根据上面ngueno的帖子,我需要appengine-api-1.0-sdk v1.9.70才能使其正常工作:
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-api-1.0-sdk</artifactId>
<version>1.9.70</version>
</dependency>
解决“无法在原始请求线程也不是由ThreadManager创建的线程的线程中进行API调用urlfetch.Fetch” 错误,此版本的appengine API,我必须将使用的HTTPTransport从 UrlFetchTransport.getDefaultInstance()更改为 GoogleNetHttpTransport.newTrustedTransport()
即:
HtpTransport httpTransport = GoogleNetHtpTransport.newTrustedTransport();
prop = new Properties();
prop.load(GoogleAuthenticator.class.getClassLoader().getResourceAsStream("config.properties"));
GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(httpTransport, gsonFactory)
// Specify the CLIENT_ID of the app that accesses the backend:
.setAudience(Collections.singletonList(prop.getProperty("google.client.id")))
.setIssuer("https://accounts.google.com")
// Or, if multiple clients access the backend:
//.setAudience(Arrays.asList(CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3))
.build();
// (Receive idTokenString by HTTPS POST)
GoogleIdToken idToken;
idToken = verifier.verify(inputToken);
所使用的所有参考和指南都指出UrlFetchTransport.getDefaultInstance()是线程安全的/最佳的选择,但在这里对我不起作用。