Mor*_*gan 17 java google-api-java-client google-oauth2
我一直在关注本教程,将Google登录支持包含在我的桌面应用中.我正在使用的图书馆是这个.
一切正常,这是authorize()方法的实现:
public Credential authorize() throws IOException {
// Load client secrets.
InputStream in = GoogleLogin.class.getResourceAsStream("/google/client_secret.json");
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
// Build flow and trigger user authorization request.
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
.setDataStoreFactory(DATA_STORE_FACTORY)
.setAccessType("offline")
.build();
Credential credential = new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
System.out.println("Credentials saved to " + DATA_STORE_DIR.getAbsolutePath());
return credential;
}
Run Code Online (Sandbox Code Playgroud)
但是,从一个Credential对象,我只能通过调用来检索访问令牌Credential.getAccessToken(),但我需要的是id token.如何在用户通过身份验证后从用户检索id_token?
Mor*_*gan 10
在开始赏金之后,我确实想出来了!通过继承AuthorizedCodeInstalledApp并提供自己的实现,可以获得Id令牌authorize()
这就是我做的......
public class GoogleAuthCodeInstalledApp extends AuthorizationCodeInstalledApp {
public GoogleAuthCodeInstalledApp(AuthorizationCodeFlow flow, VerificationCodeReceiver receiver) {
super(flow, receiver);
}
@Override
public Credential authorize(String userId) throws IOException {
try {
Credential credential = getFlow().loadCredential(userId);
if (credential != null
&& (credential.getRefreshToken() != null
|| credential.getExpiresInSeconds() == null
|| credential.getExpiresInSeconds() > 60)) {
return credential;
}
// open in browser
String redirectUri = getReceiver().getRedirectUri();
AuthorizationCodeRequestUrl authorizationUrl
= getFlow().newAuthorizationUrl().setRedirectUri(redirectUri);
onAuthorization(authorizationUrl);
// receive authorization code and exchange it for an access token
String code = getReceiver().waitForCode();
GoogleTokenResponse response = (GoogleTokenResponse) getFlow().newTokenRequest(code).setRedirectUri(redirectUri).execute();
System.out.println(response.getIdToken()); //YES, THIS IS THE ID TOKEN!!!
// store credential and return it
return getFlow().createAndStoreCredential(response, userId);
} finally {
getReceiver().stop();
}
}
}
Run Code Online (Sandbox Code Playgroud)
在你这样做之后,而不是
Credential credential = new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
Run Code Online (Sandbox Code Playgroud)
使用:
Credential credential = new GoogleAuthCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
Run Code Online (Sandbox Code Playgroud)
我找到的这个解决方案是通过添加一个CredentialCreatedListener和一个CredentialRefreshListener内部的工作GoogleAuthorizationCodeFlow.Builder.
这是示例代码:
public Credential authorize() throws IOException {
InputStream in = GoogleLogin.class.getResourceAsStream("/google/client_secret.json");
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
// Build flow and trigger user authorization request.
flow = new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
.setDataStoreFactory(DATA_STORE_FACTORY)
.setAccessType("offline")
.setCredentialCreatedListener(new AuthorizationCodeFlow.CredentialCreatedListener() {
@Override
public void onCredentialCreated(Credential credential, TokenResponse tokenResponse) throws IOException {
DATA_STORE_FACTORY.getDataStore("user").set("id_token", tokenResponse.get("id_token").toString());
}
})
.addRefreshListener(new CredentialRefreshListener() {
@Override
public void onTokenResponse(Credential credential, TokenResponse tokenResponse) throws IOException {
DATA_STORE_FACTORY.getDataStore("user").set("id_token", tokenResponse.get("id_token").toString());
}
@Override
public void onTokenErrorResponse(Credential credential, TokenErrorResponse tokenErrorResponse) throws IOException {
//handle token error response
}
})
.build();
Credential credential = new AuthorizationCodeInstalledApp(flow, serverReceiver).authorize("user");
System.out.println("Credentials saved to " + DATA_STORE_DIR.getAbsolutePath());
return credential;
}
Run Code Online (Sandbox Code Playgroud)
代码几乎是不言自明的.每当Credential通过调用创建或刷新new时credential.refreshToken(),将通知侦听器并id_token从中获取TokenResponse(实际上是GoogleTokenResponse包含id_token字段的对象),并且我们将使用默认值DataStoreFactory来保存id_token.在id_token现在将在当地持续存在,并将于每当听众自动更新credential.refreshToken()被调用.
| 归档时间: |
|
| 查看次数: |
1626 次 |
| 最近记录: |