1+ /*
2+ * Copyright 2025 The Android Open Source Project
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * https://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+
17+ package com.example.identity.credentialmanager
18+
19+ import android.content.Context
20+ import android.util.Log
21+ import androidx.credentials.CredentialManager
22+ import androidx.credentials.CustomCredential
23+ import androidx.credentials.GetCredentialRequest
24+ import androidx.credentials.GetCredentialResponse
25+ import androidx.credentials.PasswordCredential
26+ import androidx.credentials.PublicKeyCredential
27+ import androidx.credentials.exceptions.GetCredentialException
28+ import com.google.android.libraries.identity.googleid.GetGoogleIdOption
29+ import com.google.android.libraries.identity.googleid.GetSignInWithGoogleOption
30+ import com.google.android.libraries.identity.googleid.GoogleIdTokenCredential
31+ import com.google.android.libraries.identity.googleid.GoogleIdTokenParsingException
32+ import kotlinx.coroutines.coroutineScope
33+ import kotlin.math.sign
34+
35+ const val WEB_CLIENT_ID = " "
36+ class SignInWithGoogleFunctions (
37+ context : Context ,
38+ ) {
39+ private val credentialManager = CredentialManager .create(context)
40+ private val activityContext = context
41+ // Placeholder for TAG log value.
42+ val TAG = " "
43+
44+ fun createGoogleIdOption (nonce : String ): GetGoogleIdOption {
45+ // [START android_identity_siwg_instantiate_request]
46+ val googleIdOption: GetGoogleIdOption = GetGoogleIdOption .Builder ()
47+ .setFilterByAuthorizedAccounts(true )
48+ .setServerClientId(WEB_CLIENT_ID )
49+ .setAutoSelectEnabled(true )
50+ // nonce string to use when generating a Google ID token
51+ .setNonce(nonce)
52+ .build()
53+ // [END android_identity_siwg_instantiate_request]
54+
55+ return googleIdOption
56+ }
57+
58+ private val googleIdOption = createGoogleIdOption(" " )
59+
60+ suspend fun signInUser () {
61+ // [START android_identity_siwg_signin_flow_create_request]
62+ val request: GetCredentialRequest = GetCredentialRequest .Builder ()
63+ .addCredentialOption(googleIdOption)
64+ .build()
65+
66+ coroutineScope {
67+ try {
68+ val result = credentialManager.getCredential(
69+ request = request,
70+ context = activityContext,
71+ )
72+ handleSignIn(result)
73+ } catch (e: GetCredentialException ) {
74+ // Handle failure
75+ }
76+ }
77+ // [END android_identity_siwg_signin_flow_create_request]
78+ }
79+
80+ // [START android_identity_siwg_signin_flow_handle_signin]
81+ fun handleSignIn (result : GetCredentialResponse ) {
82+ // Handle the successfully returned credential.
83+ val credential = result.credential
84+ val responseJson: String
85+
86+ when (credential) {
87+
88+ // Passkey credential
89+ is PublicKeyCredential -> {
90+ // Share responseJson such as a GetCredentialResponse to your server to validate and
91+ // authenticate
92+ responseJson = credential.authenticationResponseJson
93+ }
94+
95+ // Password credential
96+ is PasswordCredential -> {
97+ // Send ID and password to your server to validate and authenticate.
98+ val username = credential.id
99+ val password = credential.password
100+ }
101+
102+ // GoogleIdToken credential
103+ is CustomCredential -> {
104+ if (credential.type == GoogleIdTokenCredential .TYPE_GOOGLE_ID_TOKEN_CREDENTIAL ) {
105+ try {
106+ // Use googleIdTokenCredential and extract the ID to validate and
107+ // authenticate on your server.
108+ val googleIdTokenCredential = GoogleIdTokenCredential
109+ .createFrom(credential.data)
110+ // You can use the members of googleIdTokenCredential directly for UX
111+ // purposes, but don't use them to store or control access to user
112+ // data. For that you first need to validate the token:
113+ // pass googleIdTokenCredential.getIdToken() to the backend server.
114+ // see [validation instructions](https://developers.google.com/identity/gsi/web/guides/verify-google-id-token)
115+ } catch (e: GoogleIdTokenParsingException ) {
116+ Log .e(TAG , " Received an invalid google id token response" , e)
117+ }
118+ } else {
119+ // Catch any unrecognized custom credential type here.
120+ Log .e(TAG , " Unexpected type of credential" )
121+ }
122+ }
123+
124+ else -> {
125+ // Catch any unrecognized credential type here.
126+ Log .e(TAG , " Unexpected type of credential" )
127+ }
128+ }
129+ }
130+ // [END android_identity_siwg_signin_flow_handle_signin]
131+
132+ fun createGoogleSignInWithGoogleOption (nonce : String ): GetSignInWithGoogleOption {
133+ // [START android_identity_siwg_get_siwg_option]
134+ val signInWithGoogleOption: GetSignInWithGoogleOption = GetSignInWithGoogleOption .Builder (
135+ serverClientId = WEB_CLIENT_ID
136+ ).setNonce(nonce)
137+ .build()
138+ // [END android_identity_siwg_get_siwg_option]
139+
140+ return signInWithGoogleOption
141+ }
142+
143+ // [START android_identity_handle_siwg_option]
144+ fun handleSignInWithGoogleOption (result : GetCredentialResponse ) {
145+ // Handle the successfully returned credential.
146+ val credential = result.credential
147+
148+ when (credential) {
149+ is CustomCredential -> {
150+ if (credential.type == GoogleIdTokenCredential .TYPE_GOOGLE_ID_TOKEN_CREDENTIAL ) {
151+ try {
152+ // Use googleIdTokenCredential and extract id to validate and
153+ // authenticate on your server.
154+ val googleIdTokenCredential = GoogleIdTokenCredential
155+ .createFrom(credential.data)
156+ } catch (e: GoogleIdTokenParsingException ) {
157+ Log .e(TAG , " Received an invalid google id token response" , e)
158+ }
159+ }
160+ else {
161+ // Catch any unrecognized credential type here.
162+ Log .e(TAG , " Unexpected type of credential" )
163+ }
164+ }
165+
166+ else -> {
167+ // Catch any unrecognized credential type here.
168+ Log .e(TAG , " Unexpected type of credential" )
169+ }
170+ }
171+ }
172+ // [END android_identity_handle_siwg_option]
173+
174+ fun googleIdOptionFalseFilter () {
175+ // [START android_identity_siwg_instantiate_request_2]
176+ val googleIdOption: GetGoogleIdOption = GetGoogleIdOption .Builder ()
177+ .setFilterByAuthorizedAccounts(false )
178+ .setServerClientId(WEB_CLIENT_ID )
179+ .build()
180+ // [END android_identity_siwg_instantiate_request_2]
181+ }
182+ }
0 commit comments