4
votes

I am new in flutter trying to access auth token from google for my backend server but every time token is invalid.

i am using FirebaseUser user await user.getIdToken() I give me a token but when I am trying to validate that token using my backend server as well as https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=mytoken and https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=mytoken this link it gives me "error_description": "Invalid Value".

I am not sure await user.getIdToken() this method is right for getting token. Other think everything ok I am getting all user information except right token. please let me know if any other way.

Below is my code:

class LoginScreen extends StatefulWidget {
  @override
  _LoginScreenState createState() => new _LoginScreenState(); 
}

class _LoginScreenState extends State<LoginScreen> {
  final FirebaseAuth auth = FirebaseAuth.instance;
  final GoogleSignIn googleSignIn = new GoogleSignIn();
  Future<http.Response> socailLogin(String authToken) async {
    var url = "http://api.ourdomain.com/user/social/login/google";
    final response = await http.post(url,
    body: json.encode({"auth_token": authToken}),
    headers: {HttpHeaders.CONTENT_TYPE: "application/json"});
    return response;
  }

  Future<FirebaseUser> googleSignin() async {
  final GoogleSignInAccount googleSignInAccount = await 
  googleSignIn.signIn();

  final GoogleSignInAuthentication googleSignInAuthentication =
    await googleSignInAccount.authentication;

  final FirebaseUser firebaseUser = await auth.signInWithGoogle(
    accessToken: googleSignInAuthentication.accessToken,
    idToken: googleSignInAuthentication.idToken);
   return firebaseUser;
 }

@override
Widget build(BuildContext context) {
final logo = Hero(
  tag: 'hero',
  child: CircleAvatar(
    backgroundColor: Colors.transparent,
    radius: 48.0,
    child: Image.asset('assets/logo.png'),
  ),
);


final googleloginButton = Padding(
  padding: EdgeInsets.symmetric(vertical: 5.0),
  child: Material(
    borderRadius: BorderRadius.circular(30.0),
    //  shadowColor: Colors.lightBlueAccent.shade100,
    // elevation: 5.0,
    child: MaterialButton(
      minWidth: 200.0,
      height: 42.0,
      onPressed: () async {
        FirebaseUser user = await googleSignin();
         String idToken = await user.getIdToken();
        if (idToken != null) {

          final http.Response response = await socailLogin(idToken);
          if (response.statusCode == 200) {
            var authToken = json.decode(response.body)['token'];
            if (authToken != null) {
              storedToken(authToken);
            }
          } else {
            print("Response status: " + response.statusCode.toString());
            print("Response body: " + response.body);
            print("errror while request");
          }
        } else {
          print("in else part not get token id from google");
        }
        Navigator.push(
          context,
          MaterialPageRoute(
            builder: (context) => HomeScreen(),
          ),
        );
      },
      color: Colors.red,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          Icon(
            Icons.bug_report,
            color: Colors.white,
          ),
          Text('Connect with Google',
              style: TextStyle(color: Colors.white)),
        ],
      ),
    ),
  ),
);

 return Scaffold(
   backgroundColor: Colors.white,
   appBar: new AppBar(
     centerTitle: true,
     title: new Text("Login"),
   ),
   body: Center(
    child: ListView(
      shrinkWrap: true,
      padding: EdgeInsets.only(left: 24.0, right: 24.0),
      children: <Widget>[
        // logo,
        googleloginButton,
        facebookloginButton,
      ],
     ),
   ),
  );
 }
}

Pleases help me.

1
were you able to solve the problem? Having the same issue too - nonybrighto
If you try to print the idToken to the console in Android, it will truncate the string to 1024 characters. And idToken may be longer than that. - William Dias
@WilliamDias thank you bro you really saved me. my problem was console. 👍❤ - Mehrdad Davoudi

1 Answers

3
votes

For backend server-side validation, you must use verifiable ID tokens to securely get the user IDs of signed-in users on the server side. ref. : https://developers.google.com/identity/sign-in/web/backend-auth

Seems that the current flutter google sign in plugin does not support getting AuthCode for backend server-side OAuth validation. ref. : https://github.com/flutter/flutter/issues/16613

I think the firebaseUser.getIdToken() cannot be used for Google API.

For https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=mytoken , you may need to pass the googleSignInAuthentication.idToken

For https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=mytoken , you may need to pass the googleSignInAuthentication.accessToken

Getting user information like user id and pass it to backend server-side is vulnerable to hackers. You should verify the idToken in backend server-side by Google API Client Libraries.