expo-auth-session/providers/google Google.useAuthRequest

Viewed 6639

I have a problem with the implementation of Google Auth within a React Native app managed with Expo. When I try to login, the response does not contain an IdToken or the information of the user and I don't understand why...

Here is my code :

 import * as Google from 'expo-auth-session/providers/google';
 
 const [request1, response1, promptAsync1] = Google.useAuthRequest({
    expoClientId: 'my-expo-id',
    iosClientId: 'my-ios-id',
  });

  React.useEffect(() => {
    if (response1?.type === 'success') {
      const { authentication } = response1;
    }
  }, [response]);

  console.log('reponse', response1)
  
  return (
  <View>
          <TouchableOpacity onPress={() => promptAsync1()}>
            <Text style={styles.connexionText}>Connect with Google</Text>
          </TouchableOpacity>
  </View>
  
  )

And here is the response :

reponse Object {
  "authentication": TokenResponse {
    "accessToken": "ya29.a0AfH6SMAEdPx5RcQP57rtdr4gV8GxFD1VSLAjovOce5X1yP-a2S6inLcSHF3KlxqmbKt0Cl6Catuyuua9Jz0rtV5psUUqWWX_QT32rXJwt9LTQywQaOzyy4cwspbOLm6W063w27f7NRiizC9RBg69-Yh09OhN",
    "expiresIn": "3599",
   ** "idToken": undefined, **
    "issuedAt": 1617701320,
    ** "refreshToken": undefined, **
    "scope": "email profile https://www.googleapis.com/auth/userinfo.profile openid https://www.googleapis.com/auth/userinfo.email",
    "state": "RwgjNwizdQ",
    "tokenType": "Bearer",
  },
  "error": null,
  "errorCode": null,
  "params": Object {
    "access_token": "ya29.a0AfH6SMAEdPx5RcQP57rtdr4gV8GxFD1VSLAjovOce5X1yP-a2S6inLcSHF3KlxqmbKt0Cl6Catuyuua9Jz0rtV5psUUqWWX_QT32rXJwt9LTQywQaOzyy4cwspbOLm6W063w27f7NRiizC9RBg69-Yh09OhN",
    "authuser": "0",
    "exp://172.20.10.3:19000/--/expo-auth-session": "",
    "expires_in": "3599",
    "prompt": "none",
    "scope": "email profile https://www.googleapis.com/auth/userinfo.profile openid https://www.googleapis.com/auth/userinfo.email",
    "state": "RwgjNwizdQ",
    "token_type": "Bearer",
  },
  "type": "success",
  "url": "exp://172.20.10.3:19000/--/expo-auth-session#state=RwgjNwizdQ&access_token=ya29.a0AfH6SMAEdPx5RcQP57rtdr4gV8GxFD1VSLAjovOce5X1yP-a2S6inLcSHF3KlxqmbKt0Cl6Catuyuua9Jz0rtV5psUUqWWX
_QT32rXJwt9LTQywQaOzyy4cwspbOLm6W063w27f7NRiizC9RBg69-Yh09OhN&token_type=Bearer&expires_in=3599&scope=email%20profile%20https://www.googleapis.com/auth/userinfo.profile%20openid%20https:/
/www.googleapis.com/auth/userinfo.email&authuser=0&prompt=none",
}

Thanks a lot in advance for your help !

3 Answers

So it's possible to get the idToken if you that's all you are looking for. You need to modify your code like this:

 const [request, response, promptAsync] = Google.useAuthRequest({
    *responseType: "id_token",*
    expoClientId: 'my-expo-id',
    iosClientId: 'my-ios-id',
  });

You will also have to access the "params" key rather than "authentication," which will show mostly null :). For me it works at least since the rest of the information was useless. HTH!

Edit: I realized that I need to get an Access Token to use google drive in my app, and thus now I need both tokens and submitted a bug report here https://github.com/expo/expo/issues/12808 to try to get this resolved.

You can get user details like this:

  1. First, get the access token from the response:

    const accessToken = response.authentication.accessToken

  2. Send GET request to the following endpoint with the accessToken you obtained in step 1:

axios.get('https://www.googleapis.com/oauth2/v3/userinfo?
access_token='+ACCESS-TOKEN-HERE)
    .then(function(response){
        const userDetails = response.data
        console.log(userDetails)
    })

Just want to add here that the id_token (Google-issued id_token) mentioned in howard's answer is a JWT that you can be decoded at jwt.io or using a jwt-decode library like jwt-decode (https://github.com/auth0/jwt-decode) or doing something like this:

      import { Buffer } from "buffer";
      // get response object 
      const id_token = response.params.id_token;

      // need to decode the id_token(jwt) to get the user object, jwt issued by Google
      const jwt_parts = id_token
        .split(".")
        .map((jwt_part) =>
          Buffer.from(
            jwt_part.replace(/-/g, "+").replace(/_/g, "/"),
            "base64"
          ).toString()
        );
      const user = JSON.parse(jwt_parts[1]); // get user object after jwt decoded
      console.log(user);

user will then have these attributes:

interface GoogleUserFromJWTPayload {
  iss: string;
  azp: string;
  aud: string;
  sub: string;
  hd: string;
  email: string;
  email_verified: boolean;
  nonce: string;
  name: string;
  picture: string;
  given_name: string;
  family_name: string;
  locale: string;
  iat: number;
  exp: number;
  jti: string;
}

But if you need both id_token and accessToken in one go, as for now it still remain as an issue/limitation?: https://github.com/expo/expo/issues/12808

Related