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