Skip to content

Google Sign-in for Flutter – Backend authentication

Hello, in the post I try to describe a solution for receiving idToken in the Flutter Google Sign-In library [https://pub.dev/packages/google_sign_in]

Using android Google Sign-in on backend

In some cases, we need to identify currently signed-in users on the backend application. For this operation, Google recommends using idToken. When the user successfully signed in mobile app sends user idToken to the backend app and verifies the integrity of the ID token and uses the user information in the token for something. More detailed information you could get there: https://developers.google.com/identity/sign-in/android/backend-auth.

The example of google sign in:

class GoogleAuth2Manager implements OAuth2Manager {
  final GoogleSignIn _googleSignIn = GoogleSignIn();

  @override
  Future<String> getIdToken() async {
    final GoogleSignInAccount googleSignInAccount =s
        await _googleSignIn.signIn();

    final GoogleSignInAuthentication googleSignInAuthentication =
        await googleSignInAccount.authentication;

    return googleSignInAuthentication.idToken;
  }
}

When idToken is got, then we might send it to backend and validate it, for instance by using google library (example from https://developers.google.com/identity/sign-in/android/backend-auth):

import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.Payload;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;

...

GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory)
    // Specify the CLIENT_ID of the app that accesses the backend:
    .setAudience(Collections.singletonList(CLIENT_ID))
    // Or, if multiple clients access the backend:
    //.setAudience(Arrays.asList(CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3))
    .build();

// (Receive idTokenString by HTTPS POST)

GoogleIdToken idToken = verifier.verify(idTokenString);
if (idToken != null) {
  Payload payload = idToken.getPayload();

  // Print user identifier
  String userId = payload.getSubject();
  System.out.println("User ID: " + userId);

  // Get profile information from payload
  String email = payload.getEmail();
  boolean emailVerified = Boolean.valueOf(payload.getEmailVerified());
  String name = (String) payload.get("name");
  String pictureUrl = (String) payload.get("picture");
  String locale = (String) payload.get("locale");
  String familyName = (String) payload.get("family_name");
  String givenName = (String) payload.get("given_name");

  // Use or store profile information
  // ...

} else {
  System.out.println("Invalid ID token.");
}

But we don’t obtain it from the example above…

I had been spending much time to find a solution to obtain idToken. And found only one:

You need to set up default google client id in strings.xml resource file. If there no files strings.xml in an android directory, you need to create it in “android/app/src/main/res/values”

And set default client id for google sign in:

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <string name="default_web_client_id">
    378641738399-***
  </string>
</resources>

And now we are getting id token after the user is authenticated.

Thanks!

Happy coding!

Leave a Reply

Your email address will not be published.