playgameservices / play-games-plugin-for-unity

Google Play Games plugin for Unity
Other
3.45k stars 962 forks source link

How to validate an auth token in my custom backend? #3307

Open KingZee opened 2 months ago

KingZee commented 2 months ago

I want to benefit from the classic google play auth experience, but i want to use my own backend once the user is logged in. I don't want to go through the entire process in android, and then start using my backend to do CRUD, because it is very insecure. Ultimately, I would like to either :

PlayGamesPlatform.Instance.RequestServerSideAccess(true, async (code) =>
 {
     //send code, which is the initial auth code to my backend and then continue the auth on my own server
     await AuthenticationService.Instance.SignInWithGooglePlayGamesAsync(code);
     Debug.Log("Authorization code: " + AuthenticationService.Instance.AccessToken);
     //send the access token to my backend, which i can then verify the authenticity of, and then continue on my own server
     Token = AuthenticationService.Instance.AccessToken;
 });

I have failed to implement both these things, and I am not sure how to work around them, I don't understand if i should be using the android's client_id and (there is no secret?), or a web client_id secret_id, or should i just use neither, i am completely lost on how to go forward here

here are snippets from my backend for more context :

    let oauth2Client = new OAuth2Client();

    oauth2Client
      .verifyIdToken({
        idToken: token,
        audience: CLIENT_ID, // Specify the CLIENT_ID of the app that accesses the backend
        // Or, if multiple clients access the backend:
        //[CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3]
      })
      .then((data) => data.getPayload())
      .then((data) => {
        console.log(data);
        return res.status(200).json(data);
      });
    let oauth2Client = new google.auth.OAuth2({
      clientId: CLIENT_ID,
      clientSecret: CLIENT_SECRET,
    });

    await oauth2Client.getToken(token, (err, tokens) => {
      if (!err) {
        oauth2Client.setCredentials(tokens);
        console.log(tokens);
      } else return next(err);
    });

none of these methods work, among other things i've tried, with both the auth token and the access token

KingZee commented 1 month ago

After a bit of searching and exploring, here is how I solved my issue :

When trying to reuse the Authorization code generated from the first login response, I needed a redirect_uri in my backend, so you're forced to add it inside the Google Play console, add http://localhost:port/xx as your redirect uri in the console, then add it in the oauth configuration builder in nodejs. (I also noted that when using the android emulator, if your callback url is localhost/auth, in order to fetch that from the emulator you'd need to query http://10.0.2.2:port/auth.)

After doing this, I realized I needed more scopes, and that my backend would fail because unity does not request enough scope, even though they are enabled in my google cloud console. The only solution to this is downgrading the unitypackage version to 0.10.14, and using PlayGamesClientConfiguration.RequestScopes();

I hope this helps someone who runs through this in the future, and I hope the ability to request new scopes is added, every other SDK (Facebook, Apple Sign in, ... ) allows me to at least get the user's email. It makes no sense for the most basic scope to request on the google console to be removed.