Search Unity

Bug Authentication fails with Invalid Token

Discussion in 'Authentication' started by DavidZobrist, Jan 22, 2022.

  1. DavidZobrist

    DavidZobrist

    Joined:
    Sep 3, 2017
    Posts:
    234
    The last week the auth sdk was working fine.
    Today I let my editor active and returend to my pc 3-4 hours later.
    When I hit play i get:


    Code (CSharp):
    1. [Authentication]: Request completed with error: {"title":"INVALID_SESSION_TOKEN","detail":"The session token is not valid.","details":[],"status":401}
    2.  
    3. UnityEngine.Logger:LogWarning (string,object)
    4. Unity.Services.Authentication.Utilities.Logger:LogWarning (object) (at Library/PackageCache/com.unity.services.authentication@1.0.0-pre.37/Runtime/Utilities/Logger.cs:16)
    5. Unity.Services.Authentication.Utilities.WebRequest:RequestCompleted (System.Threading.Tasks.TaskCompletionSource`1<string>,long,bool,bool,string,string,System.Collections.Generic.IDictionary`2<string, string>) (at Library/PackageCache/com.unity.services.authentication@1.0.0-pre.37/Runtime/Utilities/WebRequest.cs:209)

    When I restart the editor the issue persists.
    Now I wonder if this is something that could also happen to a client of the final app. (customer)
     
  2. unity_Ctri

    unity_Ctri

    Unity Technologies

    Joined:
    Oct 20, 2020
    Posts:
    81
    Hi David,

    The session token you when logging in is a quick way of logging back in for a user. Each time you log in, it is replaced. Only the most recently issued session token will work for a user. It's most commonly relied on for anonymous logins, which otherwise have no mechanism for logging back in.

    If you DM me the userID from the authentication service, I can speak to the engineers on Monday to get some specifics about what happened.

    In this case where the session token is lost, and there's no linked login provider, you'd need to instruct your code to direct the user to a login flow, which if you're only using anonymous login means a new user account.

    To avoid situations where the session token is the only way the user logs in, we encourage the linking of a login provider to the player's account. Once that's present, even if the user wipes their device and starts over, the account can still be accessed.

    Does that clear everything up?
     
    DavidZobrist likes this.
  3. DavidZobrist

    DavidZobrist

    Joined:
    Sep 3, 2017
    Posts:
    234
    unity_Ctri

    yes thanks. So we are still in development nothing is live yet. My user ID I can send you.
    For now we only use anonymous and I would like this one to work withouth issues aswell for those players that never link.

    Does it maybe occure because I have the sign-In in a singleton which is "DontDestroyOnLoad"?
    The user persisted even when hitting play mode again and again.
    And theoratically recal await SignInAnonymously(); every time.
    But it didnt seem to create a new one.

    So is there a way to check if I currently already have a session token and check if its still valid? (or should i try catch it?)
    How ever this still leaves me with the questio what to do with an invalid token when SignInAnonymoulsy does not overwrite it.
     
  4. DavidZobrist

    DavidZobrist

    Joined:
    Sep 3, 2017
    Posts:
    234
    sent a pm!
    (restarting the pc does not fix that issue)
    Just information for others in future:
    I use a singletone with dont destroy on load which maybe particpates to this issue.
     
  5. erickb_unity

    erickb_unity

    Unity Technologies

    Joined:
    Sep 1, 2021
    Posts:
    92
    Hello,

    The singleton should not be an issue.

    Can you provide the version of Authentication SDK used, your cloud project id and your session token if possible?

    Authentication SDK version can be found in your package manifest in your unity project (Packages/manifest.json)

    Cloud Project Id can be found in your ProjectSettings file under cloudProjectId. (ProjectSettings/ProjectSettings.asset)

    The session token can be found in the PlayerPrefs, the location differs depending on which platform you are on.
    https://docs.unity3d.com/ScriptReference/PlayerPrefs.html
     
    Last edited: Jan 24, 2022
  6. DavidZobrist

    DavidZobrist

    Joined:
    Sep 3, 2017
    Posts:
    234
    Hi Erick,

    thanks for looking into this issue:

    "com.unity.services.cloudcode": "1.0.0-pre.6",
    "com.unity.services.authentication": "1.0.0-pre.37",
    "com.unity.services.cloudsave": "1.0.0-pre.3"


    cloudProjectId: abfb5932-efea-4a54-814b-6c42e1b95645
     
  7. DavidZobrist

    DavidZobrist

    Joined:
    Sep 3, 2017
    Posts:
    234
    Session Id i can find via registry

    abfb5932-efea-4a54-814b-6c42e1b95645.default.unity.services.authentication.session_token_h3622902611
     
  8. DavidZobrist

    DavidZobrist

    Joined:
    Sep 3, 2017
    Posts:
    234
    @erickboulay

    Any news on that issue?
    I still have auth commented out in our code as it still has the issue with the corrupted session token.
    Code (CSharp):
    1.    //   await SignInAnonymously();
     
  9. erickb_unity

    erickb_unity

    Unity Technologies

    Joined:
    Sep 1, 2021
    Posts:
    92
    Hey,

    Sorry for the delay for the reply,
    There is another piece of information that would be useful for us if you can provide it to us.

    Essentially, the session token key you provided is used to get the session token value in the player prefs, if you could provide us that value, it would be very useful.

    You could get it like this:
    Debug.Log(PlayerPrefs.GetString("abfb5932-efea-4a54-814b-6c42e1b95645.default.unity.services.authentication.session_token_h3622902611"));

    We are still looking into a few possible solutions for the backend to ensure this doesn't happen - this may take a bit more time.

    In the meantime, the best solution is to clear the session token (AuthenticationService.Instance.ClearSessionToken) when you get the error 'INVALID_SESSION_TOKEN'.
    This will be done automatically in the next version of the Authentication SDK.
     
    DavidZobrist likes this.
  10. DavidZobrist

    DavidZobrist

    Joined:
    Sep 3, 2017
    Posts:
    234
    Thanks
    here the output of the debug.log

    JM8VbT6bG1sGwJtekfebpRTiSv-aJdsQNE29y8A7ucamI6xN4yVTnQk8rSKehqDUwQHD14tpt8oIHJwYpBgZC0lUGTZNXM-Y0EXh3RRR10wH_nzW81Dyv1nJ1SS2ChtMJ2b53vB7Z0sCPXUI93ui3oNaSnWlAi7yGNp5LFcNh9A.GIhBBUCzyd8hHNs-wKWeLZyKifJsAhJAxLtt7BtZp8I
     
  11. DavidZobrist

    DavidZobrist

    Joined:
    Sep 3, 2017
    Posts:
    234
    @erickboulay
    (AuthenticationService.Instance.ClearSessionToken)
    worked

    yeah I realized that anonym users are refered as their session token.
    So everytime I get a new session token the data is not longer coupled to the player, which has not changed his device.

    Session token 1:
    7oBGbe6Wys2BBokd6AwuTLbOrwMl

    Session token2:
    GkNbHbIi6aMX5CW3WLOH7F8VNWGB

    Etc


    The expected behaviour would be:
    Use an Id that is couple with the device ID. So even if a new session has to be created that user still has access to his data aslong he uses the same device.
     
  12. erickb_unity

    erickb_unity

    Unity Technologies

    Joined:
    Sep 1, 2021
    Posts:
    92
    Hey,

    Thanks for providing the information, it's really helpful and we're digging into the problem now.

    Let me reassure you that this is not the intended behavior, you should always get the same player when using anonymous/session token login and you shouldn't need to worry about the token logic. This is high priority and we will fix this as soon as we can.
     
    DavidZobrist likes this.
  13. DavidZobrist

    DavidZobrist

    Joined:
    Sep 3, 2017
    Posts:
    234
    Thank you
     
  14. vengefullfoot

    vengefullfoot

    Joined:
    Sep 24, 2018
    Posts:
    31
    Hello, I ave exactly the same issue in the player while testing (when testing on devices it works). What is the procedure to have the player authenticating again ?
     
  15. erickb_unity

    erickb_unity

    Unity Technologies

    Joined:
    Sep 1, 2021
    Posts:
    92
    unity_Ctri likes this.
  16. vengefullfoot

    vengefullfoot

    Joined:
    Sep 24, 2018
    Posts:
    31
    Thank you very much. It worked nicely (actually clearing the playerprefs didn't, but the clearing the token in code worked). As you mentioned at the beginning this token is supposed to be reinitialized at each start, is it good practice to keep AuthenticationService.Instance.ClearSessionToken in the code to be executed each time and force the reinitialization of the token in case it's blocked ?
     
  17. erickb_unity

    erickb_unity

    Unity Technologies

    Joined:
    Sep 1, 2021
    Posts:
    92
    Hello,

    You should not clear this token as it is used by anonymous login to access the account you were previously signed in to.
    Clearing the session token is only needed when you get the INVALID_SESSION_TOKEN error specifically.

    However, this error should no longer occur for new tokens in you receive in the future.
    If it happens to you again, please report it to us.
     
  18. vengefullfoot

    vengefullfoot

    Joined:
    Sep 24, 2018
    Posts:
    31
    Ok, thank you very much.
     
  19. codoraunity

    codoraunity

    Joined:
    Sep 22, 2022
    Posts:
    4
    Hi all, I know this is an old thread but facing the same issue in my game implementation. When i use SignInAnonymouslyAsync() and hit play the user get logged in successfully, but when stop the game and start it again it creates a new user and the old access token gets empty. i am using the below sample code for anonymous login.
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using System.Threading.Tasks;
    4. using Unity.Services.Authentication;
    5. using Unity.Services.Core;
    6. using UnityEngine;
    7.  
    8. public class Authentication : MonoBehaviour
    9. {
    10.     internal async Task Awake()
    11.     {
    12.         await UnityServices.InitializeAsync();
    13.         await SignInAnonymously();
    14.     }
    15.  
    16.     private async Task SignInAnonymously()
    17.     {
    18.         Debug.Log(AuthenticationService.Instance.AccessToken);
    19.         AuthenticationService.Instance.SignedIn += () =>
    20.         {
    21.             var playerId = AuthenticationService.Instance.PlayerId;
    22.  
    23.             Debug.Log("Signed in as: " + playerId);
    24.         };
    25.         AuthenticationService.Instance.SignInFailed += s =>
    26.         {
    27.                 // Take some action here...
    28.                 Debug.Log(s);
    29.         };
    30.  
    31.         await AuthenticationService.Instance.SignInAnonymouslyAsync();
    32.     }
    33. }
    34. }
     
  20. vuthang

    vuthang

    Joined:
    Mar 7, 2017
    Posts:
    50
    Hi @erickb_unity , I get this error when I try re-login after logout: Unity.Services.Authentication.AuthenticationException: unable to validate token ---> Unity.Services.Authentication.WebRequestException: {"title":"PERMISSION_DENIED","detail":"unable to validate token","details":[],"status":401}. Help me fix this please
     
  21. vuthang

    vuthang

    Joined:
    Mar 7, 2017
    Posts:
    50
    I use PlayGamesPlatform.Instance.ManuallyAuthenticate instead of PlayGamesPlatform.Instance.Authenticate. Now I can logout and re-login success every time
     
  22. IneptStudio

    IneptStudio

    Joined:
    Mar 7, 2022
    Posts:
    12
    Hi i am using anonymous login and it is working perfectly, i got userid, accesstoken etc, and i have stored them in a playerpref too, but my question is how can i relogin someone with same details . As i am using unity leaderboard and it is saying: LeaderboardsException: Access token is missing - ensure you are signed in through the Authentication SDK and try again.

    It happen after i close the game and run it again.
     
  23. MiTschMR

    MiTschMR

    Joined:
    Aug 28, 2018
    Posts:
    489
    What’s your sign in flow looking like? What do you use to sign in? When do you call the leaderboard service?
     
  24. IneptStudio

    IneptStudio

    Joined:
    Mar 7, 2022
    Posts:
    12
    For SignIn i have two option :
    1. Anonymous
    2. Google play games login

    I want to use them with Unity Cloud.
    Now after successfull login when i load leaderbord it works fine , but after closing the game it does not works , here is my code:


    Code (CSharp):
    1. using System.Threading.Tasks;
    2. using Unity.Services.Authentication;
    3. using Unity.Services.Core;
    4. using UnityEngine;
    5. using UnityEngine.SceneManagement;
    6. public class splashScript : MonoBehaviour
    7. {
    8.     public static splashScript instance;
    9.     public GameObject loginOption;
    10.     public GameObject loadingTxt;
    11.     public GameObject loadingScreen;
    12.  
    13.     private void Awake()
    14.     {
    15.         instance = this;
    16.         Init();
    17.     }
    18.     async void Init()
    19.     {
    20.         await UnityServices.InitializeAsync();
    21.     }
    22.     private void Start()
    23.     {
    24.          checkForLogin();
    25.     }
    26.     public void checkForLogin()
    27.     {
    28.         if (string.IsNullOrEmpty(PlayerPref.GetString("userIdPref")))//not log in
    29.         {
    30.             loginOption.SetActive(true);
    31.             loadingTxt.SetActive(false);
    32.         }
    33.         else {
    34.             loginOption.SetActive(false);
    35.             loadingTxt.SetActive(true);
    36.          
    37.             Invoke(nameof(LaunchGame),1f);
    38.         }
    39.     }
    40.     void LaunchGame() {
    41.         SceneManager.LoadScene(1);//in that scene i am loading leaderboard, which will work fine if i am properly authenticated, so i think error is in this script only
    42.     }
    43.  
    44.     public async void SignInAnonymous()// call by click of a button in scene
    45.     {
    46.         await signInAnonymous();
    47.     }
    48.     async Task signInAnonymous()
    49.     {
    50.    
    51.         // Check if a cached player already exists by checking if the session token exists
    52.         if (AuthenticationService.Instance.SessionTokenExists)
    53.         {
    54.             // if not, then do nothing
    55.             print(AuthenticationService.Instance.PlayerId);
    56.             return;
    57.         }
    58.         // Sign in Anonymously
    59.         // This call will sign in the cached player.
    60.         try
    61.         {
    62.             await AuthenticationService.Instance.SignInAnonymouslyAsync();
    63.             Debug.Log("Sign in anonymously succeeded!");
    64.             print("Player Id:" + AuthenticationService.Instance.PlayerId);
    65.          
    66.          
    67.             PlayerPref.SetString("userIdPref", AuthenticationService.Instance.PlayerId);
    68.        
    69.             checkForLogin();//now leaderboard will work fine, as i just logged in, but not work next time
    70.          
    71.         }
    72.         catch (AuthenticationException ex)
    73.         {
    74.          
    75.             print("Sign in failed!!"+ex);
    76.         }
    77.         catch (RequestFailedException ex)
    78.         {
    79.        
    80.             print("Sign in failed!!"+ex);
    81.         }
    82.     }
    83.  
    84. }

    i hope you understand the problem from my code, my only problem is, how can i login a user if i already have access token from previous successfull signin.
     
  25. MiTschMR

    MiTschMR

    Joined:
    Aug 28, 2018
    Posts:
    489
    You still need to call SignInAnonymously to get a fresh token and sign the player in. Imagine the player doesn’t pay for several weeks, a token will never be valid for such a long time.
     
  26. IneptStudio

    IneptStudio

    Joined:
    Mar 7, 2022
    Posts:
    12
    Hi i just updated my code a little , now i am checking if sessionTokenExsist or not, please have a look

    Code (CSharp):
    1. using System.Threading.Tasks;
    2. using Unity.Services.Authentication;
    3. using Unity.Services.Core;
    4. using UnityEngine;
    5. using UnityEngine.SceneManagement;
    6.  
    7. public class splashScript : MonoBehaviour
    8. {
    9.     public static splashScript instance;
    10.  
    11.     public GameObject loginOption;
    12.     public GameObject loadingTxt;
    13.     public GameObject loadingScreen;
    14.  
    15.  
    16.     private void Awake()
    17.     {
    18.         instance = this;
    19.         Init();
    20.     }
    21.     async void Init()
    22.     {
    23.         await UnityServices.InitializeAsync();
    24.     }
    25.     private void Start()
    26.     {
    27.        checkForLogin();
    28.     }
    29.  
    30.     public void checkForLogin()
    31.     {
    32.        
    33.  
    34.         if (AuthenticationService.Instance.SessionTokenExists)
    35.         {
    36.             print("token exsist: "+ AuthenticationService.Instance.PlayerId);
    37.             loginOption.SetActive(false);
    38.             loadingTxt.SetActive(true);
    39.             Invoke(nameof(LaunchGame), 1f);//Launching game
    40.         }
    41.         else {
    42.             print("No token");
    43.             loginOption.SetActive(true);
    44.             loadingTxt.SetActive(false);
    45.         }
    46.     }
    47.  
    48.  
    49.     void LaunchGame() {
    50.         SceneManager.LoadScene(1);
    51.     }
    52.  
    53.  
    54.     public async void SignInAnonymous()
    55.     {
    56.         await signInAnonymous();
    57.     }
    58.  
    59.     async Task signInAnonymous()
    60.     {
    61.      
    62.         // Check if a cached player already exists by checking if the session token exists
    63.         if (AuthenticationService.Instance.SessionTokenExists)
    64.         {
    65.             // if not, then do nothing
    66.             print("previous player:  "+AuthenticationService.Instance.PlayerId);
    67.             SavedDataScript.SetValueString(SavedDataScript.userIdPref, AuthenticationService.Instance.PlayerId);
    68.  
    69.             checkForLogin();
    70.             return;
    71.         }
    72.  
    73.         // Sign in Anonymously
    74.         // This call will sign in the cached player.
    75.         try
    76.         {
    77.             await AuthenticationService.Instance.SignInAnonymouslyAsync();
    78.             Debug.Log("Sign in anonymously succeeded!");
    79.  
    80.             print("Player Id:" + AuthenticationService.Instance.PlayerId);
    81.             string accessToken = AuthenticationService.Instance.AccessToken;
    82.             SavedDataScript.SetValueString(SavedDataScript.userNamePref, "Tester" + Random.Range(000, 999));
    83.             SavedDataScript.SetValueString(SavedDataScript.userIdPref, AuthenticationService.Instance.PlayerId);
    84.             SavedDataScript.SetValueString(SavedDataScript.accessToken, accessToken);
    85.  
    86.             checkForLogin();
    87.             // logTxt.text = "Player id:" + AuthenticationService.Instance.PlayerId;
    88.         }
    89.         catch (AuthenticationException ex)
    90.         {
    91.             // Compare error code to AuthenticationErrorCodes
    92.             // Notify the player with the proper error message
    93.             // Debug.LogException(ex);
    94.             print("Sign in failed!!"+ex);
    95.  
    96.         }
    97.         catch (RequestFailedException ex)
    98.         {
    99.             // Compare error code to CommonErrorCodes
    100.             // Notify the player with the proper error message
    101.             //Debug.LogException(ex);
    102.             print("Sign in failed!!"+ex);
    103.  
    104.         }
    105.     }
    106.  
    107. }
    108.  


    Now in my next scene where i show the data in leader board , it still throwing an error , even when my session token exsist .

    error:
    LeaderboardsException: Access token is missing - ensure you are signed in through the Authentication SDK and try again.
    Unity.Services.Leaderboards.Internal.LeaderboardsApiClientInternal.ValidateRequiredDependencies




    Code (CSharp):
    1. public void ShowLeaderboard() {
    2.     loadingLeaderboard.SetActive(true);
    3.     leaderboardUi.SetActive(true);
    4.     GetScores();
    5. }
    6. public async void GetScores()
    7. {
    8.     var scoresResponse = await LeaderboardsService.Instance
    9.         .GetScoresAsync(leaderboardId);
    10.     Debug.Log(JsonConvert.SerializeObject(scoresResponse));
    11.     lData = JsonUtility.FromJson<leaderboardData>(JsonConvert.SerializeObject(scoresResponse));
    12.     loadingLeaderboard.SetActive(false);
    13.  
    14.     UpdateLeaderboard();
    15. }

    I hope you understand my problem
     
  27. MiTschMR

    MiTschMR

    Joined:
    Aug 28, 2018
    Posts:
    489
    You fundamentally don’t understand how authentication works, sorry. You need to sign in every time you start the game! You don’t need to store an access token, the SDK already does this for you. Simply, before invoking the game scene, call SignInAnonymously.
     
  28. IneptStudio

    IneptStudio

    Joined:
    Mar 7, 2022
    Posts:
    12
    Got it working, Thanks,
    One last thing, After successfull login can we see the list of users in unity dashboard , just like we can see in firebase.
    As i am unable to find a option in unity cloud under authentication


    like this
     
    AntonioModer likes this.
  29. MiTschMR

    MiTschMR

    Joined:
    Aug 28, 2018
    Posts:
    489
    In the Unity dashboard, go to Live Ops, Authentication and then Player Management.
     
    AntonioModer likes this.
  30. naruto93

    naruto93

    Joined:
    May 6, 2015
    Posts:
    17
    Hi guys, I have this issue. I want to make Sign in with a special ID by
    AuthenticationService.Instance.ProcessAuthenticationTokens. But it always returns this error "[Authentication]: That is not a valid token (expected 3 parts but has 1).".
    So how can I create a token with my string value, thanks!