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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With