# Authenticating user via google game services: Unauthorized

**URL:** <https://forum.heroiclabs.com/t/authenticating-user-via-google-game-services-unauthorized/53>\
**Category:** Local Setup\
**Tags:** authentication\
**Created:** [July 4, 2019, 4:25pm UTC](https://forum.heroiclabs.com/t/authenticating-user-via-google-game-services-unauthorized/53 "2019-07-04T16:25:53Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![oscargoldman](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/oscargoldman/32/28_2.png) [@oscargoldman](https://forum.heroiclabs.com/u/oscargoldman)\
**Post date:** [July 4, 2019, 4:25pm UTC](https://forum.heroiclabs.com/t/authenticating-user-via-google-game-services-unauthorized/53/1 "2019-07-04T16:25:53Z")

</div>

I’m running nakama on my local dev environment, and I’m trying to authenticate a nakama user via google game services. I am successfully logging in a google user on the unity client, and getting back an auth token. But when I try to authenticate with the auth token, I get back Unauthorized. I am guessing that I need to add my IP to the web client oauth linked app in the google console - is this correct, and what port would nakama be using to get this authentication?  
Is this even possible to do from an IP or does it have to be a qualified domain name that is authorized?

---

<div class="post-metadata">

**Author:** ![gupta-vaibhav](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/gupta-vaibhav/32/146_2.png) [@gupta-vaibhav](https://forum.heroiclabs.com/u/gupta-vaibhav)\
**Post date:** [July 5, 2019, 1:10pm UTC](https://forum.heroiclabs.com/t/authenticating-user-via-google-game-services-unauthorized/53/2 "2019-07-05T13:10:44Z")

</div>

Hi, we have implemented the Google Login in dev and production environment and might be able to contribute. It may not have anything to do with the IP address since the Unity client also must’ve used some IP address to connect, which you wouldn’t have whitelisted either. Could you:

- Share any error logs / messages from the server
- Share the code snippet from Unity that you are using to authorise, i.e. the code where you receive the auth token and send it to Nakama.

---

<div class="post-metadata">

**Author:** ![novabyte](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/novabyte/32/1324_2.png) [@novabyte](https://forum.heroiclabs.com/u/novabyte)\
**Post date:** [July 5, 2019, 1:43pm UTC](https://forum.heroiclabs.com/t/authenticating-user-via-google-game-services-unauthorized/53/3 "2019-07-05T13:43:06Z")

</div>

Hi @oscargoldman. I’ll assume you use Unity GPGS sdk to connect with Google.

> But when I try to authenticate with the auth token, I get back Unauthorized.

Which token do you use? In the Unity GPGS sdk it’s called the `PlayerIdToken` which you pass into the Nakama Unity client. i.e.

```auto
var client = new Client("yourkey"); // set via cmdflag: --socket.server_key <val>
var playerIdToken = "someval"; // obtained from GPGS sdk
var session = await client.AuthenticateGoogleAsync(playerIdToken, "someusername", true);

```

> is this correct, and what port would nakama be using to get this authentication?

IIRC you do not need to setup additional permissions in the Google Play console.

> Is this even possible to do from an IP or does it have to be a qualified domain name that is authorized?

Nakama server follows rules set by Google for server to server validation of a player via a token. Maybe @zyro can add more details here.

---

<div class="post-metadata">

**Author:** ![zyro](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/zyro/32/14_2.png) [@zyro](https://forum.heroiclabs.com/u/zyro)\
**Post date:** [July 5, 2019, 1:51pm UTC](https://forum.heroiclabs.com/t/authenticating-user-via-google-game-services-unauthorized/53/4 "2019-07-05T13:51:37Z")

</div>

@novabyte is right, there’s no extra configuration needed to connect to Google in the server or in your Google admin dashboard.

If you’re using something like the GPGS plugin for Unity I think [this is the right token to use](https://github.com/playgameservices/play-games-plugin-for-unity#retrieving-players-id-token). Have you tried that token?

---

<div class="post-metadata">

**Author:** ![oscargoldman](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/oscargoldman/32/28_2.png) [@oscargoldman](https://forum.heroiclabs.com/u/oscargoldman)\
**Post date:** [July 5, 2019, 6:51pm UTC](https://forum.heroiclabs.com/t/authenticating-user-via-google-game-services-unauthorized/53/5 "2019-07-05T18:51:13Z")

</div>

Thanks guys. We’re using the Voxel Busters Native Plugin pack which provides a GameServices wrapper which works for both IOS and Android. We are authenticating from the client with game services, and in the credentials object we get back, there is only a server authentication code. We do get a Local user object returned that includes an Identifier (g08837891035984601862) but using that with the AuthenticateGoogleAsync results in a 401 Unauthorized response. I’m waiting on Voxel Busters to get back to me to see how we get the Player Access token using their API.

---

<div class="post-metadata">

**Author:** ![novabyte](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/novabyte/32/1324_2.png) [@novabyte](https://forum.heroiclabs.com/u/novabyte)\
**Post date:** [July 6, 2019, 5:16pm UTC](https://forum.heroiclabs.com/t/authenticating-user-via-google-game-services-unauthorized/53/6 "2019-07-06T17:16:51Z")

</div>

@oscargoldman That’s good to know. Definitely drop back in and report when you know how to obtain the PlayerIdToken from the Voxel Busters Native Plugin. 👍

---

<div class="post-metadata">

**Author:** ![oscargoldman](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/oscargoldman/32/28_2.png) [@oscargoldman](https://forum.heroiclabs.com/u/oscargoldman)\
**Post date:** [July 10, 2019, 3:20pm UTC](https://forum.heroiclabs.com/t/authenticating-user-via-google-game-services-unauthorized/53/7 "2019-07-10T15:20:27Z")

</div>

we haven’t heard back from voxel busters yet, they said they’re looking into adding the player access token. In the meantime we’ve switched to the GPGS sdk and it’s working fine with Nakama. Seeing that the same issue applies with ios - even more so since the Unity.SocialPlatforms api doesn’t have any of the info we need to authenticate nakama and ios, we may just not use Native Plugins for game services.

---

<div class="post-metadata">

**Author:** ![novabyte](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/novabyte/32/1324_2.png) [@novabyte](https://forum.heroiclabs.com/u/novabyte)\
**Post date:** [July 10, 2019, 8:31pm UTC](https://forum.heroiclabs.com/t/authenticating-user-via-google-game-services-unauthorized/53/8 "2019-07-10T20:31:05Z")

</div>

Ok thanks for the note @oscargoldman. We recommend this plugin for [Game Center Auth](https://github.com/desertkun/GameCenterAuth) integration within your Unity project code.

When you get the chance it’d be great if you could paste some example code to show how you’ve authenticated with the GPGS unity sdk and Nakama.

---

<div class="post-metadata">

**Author:** ![oscargoldman](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/oscargoldman/32/28_2.png) [@oscargoldman](https://forum.heroiclabs.com/u/oscargoldman)\
**Post date:** [July 12, 2019, 3:50pm UTC](https://forum.heroiclabs.com/t/authenticating-user-via-google-game-services-unauthorized/53/10 "2019-07-12T15:50:18Z")

</div>

oh I think maybe the handlers have to be static methods all the way.

---

<div class="post-metadata">

**Author:** ![novabyte](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/novabyte/32/1324_2.png) [@novabyte](https://forum.heroiclabs.com/u/novabyte)\
**Post date:** [July 19, 2019, 6:05pm UTC](https://forum.heroiclabs.com/t/authenticating-user-via-google-game-services-unauthorized/53/11 "2019-07-19T18:05:50Z")

</div>

@oscargoldman Were you able to configure and connect with both Game Center and Google Play Games in your Unity project code? If so I think it’d be great to share some example code if you can and we’ll mark the thread complete. 🙂

---

<div class="post-metadata">

**Author:** ![oscargoldman](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/oscargoldman/32/28_2.png) [@oscargoldman](https://forum.heroiclabs.com/u/oscargoldman)\
**Post date:** [July 20, 2019, 8:21pm UTC](https://forum.heroiclabs.com/t/authenticating-user-via-google-game-services-unauthorized/53/12 "2019-07-20T20:21:30Z")

</div>

Sure, I can share our game services manager we use. Im being told I can’t upload attachments so I’ll just paste the whole thing here:

```auto
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;

#if UNITY_ANDROID
using GooglePlayGames;
using GooglePlayGames.BasicApi;
using UnityEngine.SocialPlatforms;
#endif
#if UNITY_IOS
using UnityEngine.SocialPlatforms.GameCenter;
using Online;
using AOT;
#endif

namespace com.gamescompany.lyrical.business.login_system
{
    public class GameServicesManager
    {
        private static GameServicesManager _instance;

        private bool _isAvailable = false;
        public static string GAME_CENTER_FAILED = "GAME_CENTER_FAILED";

        public static GameServicesManager getInstance
        {
            get
            {
                if (_instance == null)
                    _instance = new GameServicesManager();
                return _instance;
            }
        }

        public void init()
        {
#if UNITY_ANDROID
            PlayGamesClientConfiguration config = new PlayGamesClientConfiguration.Builder()
                 .RequestEmail()
                 .RequestServerAuthCode(false)
                 .RequestIdToken()
                 .Build();

            PlayGamesPlatform.InitializeInstance(config);
            PlayGamesPlatform.DebugLogEnabled = true;
            PlayGamesPlatform.Activate();
#endif
        }

#if UNITY_ANDROID
        public async Task<string> connect()
        {
            bool success = await login();

            if (success)
            {
                DebugUtils.Log("GP login success");
                return PlayGamesPlatform.Instance.GetIdToken();
            }
            else
            {
                DebugUtils.Log("GP login fail");
                return string.Empty;
            }
        }
#endif

#if UNITY_IOS
        [MonoPInvokeCallback(typeof(GameCenterSignature.OnFailed))]
        public static void onFailed(string Reason)
        {
            Debug.Log("Failed to connect to Game Center");
            response.Add(GAME_CENTER_FAILED, true);
        }

        [MonoPInvokeCallback(typeof(GameCenterSignature.OnSucceeded))]
        public static void onSuccess(string PublicKeyUrl, ulong timestamp, string signature, string salt, string playerID, string alias, string bundleID)
        {
            Debug.Log("Succeeded authorization to gamecenter: \n" +
            "PublicKeyUrl=" + PublicKeyUrl + "\n" +
            "timestamp=" + timestamp + "\n" +
            "signature=" + signature + "\n" +
            "salt=" + salt + "\n" +
            "playerID=" + playerID + "\n" +
            "alias=" + alias + "\n" +
            "bundleID=" + bundleID);

            response.Add("PublicKeyUrl", PublicKeyUrl);
            response.Add("timestamp", timestamp);
            response.Add("signature", signature);
            response.Add("salt", salt);
            response.Add("playerID", playerID);
            response.Add("alias", alias);
            response.Add("bundleID", bundleID);
        }

        public static Dictionary<string, object> response = new Dictionary<string, object>();

        public async Task<Dictionary<string, object>> connect()
        {
            bool success = await login();
            
            GameCenterSignature.Generate(onSuccess, onFailed);

            await Task.Run(() =>
            {
                while (response.Count == 0) { }
            });
            return response;
        }

#endif

        private bool completed = false, success = false;

        private async Task<bool> login()
        {
            bool complete = false;
            if (Social.localUser.authenticated == false)
            {
                Social.localUser.Authenticate((bool isAuthenticated) =>
                {
                    complete = true;
                    success = isAuthenticated;
                    Debug.Log("Social isAuthenticated");
                });
            }
            else
            {
                success = true;
                completed = true;
                Debug.Log("Social isAuthenticated");
            }
            await Task.Run(() =>
            {
                while (!complete) { }
            });
            return success;
        }
    }
}

```

---

<div class="post-metadata">

**Author:** ![oscargoldman](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/oscargoldman/32/28_2.png) [@oscargoldman](https://forum.heroiclabs.com/u/oscargoldman)\
**Post date:** [July 20, 2019, 8:22pm UTC](https://forum.heroiclabs.com/t/authenticating-user-via-google-game-services-unauthorized/53/13 "2019-07-20T20:22:56Z")

</div>

Here are the NakamaManager calls that use the GameServicesManager:

```auto
public static async Task<NakamaResponse> signInGameServices(string gameServicesId, string username)
{
    NakamaResponse response = new NakamaResponse();
    try
    {
        session = await _instance.client.AuthenticateGoogleAsync(gameServicesId,username ,true);
        response.payload = await processSession(session);
    }
    catch (ApiResponseException e)
    {
        DebugUtils.Log($"NakamaManager::signInGameServices server error: {e.StatusCode}");
        response.error = UserDataManager.ERROR_SERVER;
    }
    catch (Exception)
    {
        DebugUtils.Log($"NakamaManager::signInGameServices internet error");
        response.error = UserDataManager.ERROR_INTERNET;
    }
    return response;
}

```

```auto
public static async Task<NakamaResponse> signInGameCenter (Dictionary<string,object> payload)
{
    NakamaResponse response = new NakamaResponse();
    try
    {
        session = await _instance.client.AuthenticateGameCenterAsync(
            payload["bundleID"].ToString(),
            payload["playerID"].ToString(),
            payload["publicKeyURL"].ToString(),
            payload["salt"].ToString(),
            payload["signature"].ToString(),
            payload["timestamp"].ToString());
        response.payload = await processSession(session);
    }
    catch (ApiResponseException e)
    {
        DebugUtils.Log($"NakamaManager::signInPlayCenter server error: {e.StatusCode}");
        response.error = UserDataManager.ERROR_SERVER;
    }
    catch (Exception)
    {
        DebugUtils.Log($"NakamaManager::signInPlayCenter internet error");
        response.error = UserDataManager.ERROR_INTERNET;
    }
    return response;
}

```

---

<div class="post-metadata">

**Author:** ![novabyte](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/novabyte/32/1324_2.png) [@novabyte](https://forum.heroiclabs.com/u/novabyte)\
**Post date:** [July 22, 2019, 5:14am UTC](https://forum.heroiclabs.com/t/authenticating-user-via-google-game-services-unauthorized/53/14 "2019-07-22T05:14:18Z")

</div>

Thanks @oscargoldman. That’s awesome.
