We are updating our application to use the CredentialManager
for logging in, but we are not finding a way to get the serverAuthCode
from this new implementation. We need this information to maintain compatibility with our backend, which expects this information instead of the idToken
.
Our old implementation:
val task = GoogleSignIn.getSignedInAccountFromIntent(activityResult.data)
val account = try {
task.getResult(ApiException::class.java)
} catch (e: ApiException) {
// Something treatment here
null
}
val serverAuthCode = account?.serverAuthCode
// endpoint call
New implementation:
val googleIdOption = GetSignInWithGoogleOption.Builder("our serverClientId").build()
val request = GetCredentialRequest.Builder()
.addCredentialOption(googleIdOption)
.build()
val credentialManager = CredentialManager.create(context)
val response = credentialManager.getCredential(context, request)
val credential = response.credential
if (credential is CustomCredential && credential.type == TYPE_GOOGLE_ID_TOKEN_CREDENTIAL) {
try {
val googleIdTokenCredential = GoogleIdTokenCredential.createFrom(credential.data)
// rest of the code and endpoint call
As I mentioned above, in this new implementation, it is not possible to get the serverAuthCode
, only the idToken
.
How should we go about getting the serverAuthCode
and maintaining compatibility with our backend?
Here’s how I’m handling the authorization:
val authorizationLauncher = rememberAuthorizationLauncher()
val requestedScopes = listOf(
Scope(Scopes.PLUS_ME),
Scope(Scopes.PROFILE),
Scope("https://www.googleapis.com/auth/user.birthday.read"),
Scope("https://www.googleapis.com/auth/user.gender.read"),
Scope("https://www.googleapis.com/auth/userinfo.email")
)
val authorizationRequest = AuthorizationRequest.builder().setRequestedScopes(requestedScopes).build()
Identity.getAuthorizationClient(context)
.authorize(authorizationRequest)
.addOnSuccessListener { authorizationResult ->
if (authorizationResult.hasResolution()) {
authorizationResult.pendingIntent?.intentSender?.let { intentSender ->
authorizationLauncher.launch(IntentSenderRequest.Builder(intentSender).build())
}
} else {
authorizationResult.serverAuthCode // always null
}
}
@Composable
private fun rememberAuthorizationLauncher(
activity: Activity = LocalActivity.current
) = rememberLauncherForActivityResult(
contract = ActivityResultContracts.StartIntentSenderForResult()
) { activityResult ->
if (activityResult.resultCode == Activity.RESULT_OK) {
Identity.getAuthorizationClient(activity).getAuthorizationResultFromIntent(activityResult.data)
}
}
The solution for this is to request offline access when building the authorization request:
AuthorizationRequest.builder()
.setRequestedScopes(requestedScopes)
.requestOfflineAccess(SERVER_CLIENT_ID) // THIS!
.build()
See a working sample here