Search Unity

Question iOS SignInWithAppleAsync gives PERMISSION_DENIED

Discussion in 'Authentication' started by mhardy, Jan 24, 2022.

  1. mhardy

    mhardy

    Joined:
    Apr 3, 2011
    Posts:
    48
    I have SignIn with Apple working but am running into a PERMISSION_DENIED issue when I try to Link or SignIn with the account. I also have some questions as the docs are very light on this.

    Questions
    1. AuthenticationService.Instance.LinkWithAppleAsync(idToken)
    - this method requires a string. IAppleIDCredential.IdentityToken is a byte[]. I assume it's base64 encoded so I am using Convert.ToBase64String() to get a string.
    - is this the correct string it wants for idToken?

    2. What does LinkWithAppleAsync actually do? I assume it links the anonymous PlayerId to this apple account. But what if they login anonymously on a different device getting a different PlayerId.
    Then they sign in with Apple, will it change the PlayerId to the one previously linked?

    3. Is there a proper way to know if they've previously linked an account (other than watching for the AuthenticationErrorCodes.AccountAlreadyLinked exception)? A lot needs to be done if they login again from a new/different device.

    I'm using the pre.37 package.

    Sequence I'm trying to use (is this correct?)
    A) AuthenticationService.Instance.SignInAnonymouslyAsync()
    - works fine. get PlayerId back.
    B) Click SignIn button in App
    C) _appleAuthManager.LoginWithAppleId(...)
    - works fine. returns name, email, idtoken
    D) Save off Name, Email, Convert.ToBase64String(IdentityToken)

    -- Now to try to Link and/or Sign in with Apple

    E) AuthenticationService.Instance.SignOut(); -- need this else 'The player is already signed in' from the Anonymous sign in
    F) AuthenticationService.Instance.SignInWithAppleAsync(idToken); -- using the Base64 encoded IAppleIDCredential.IdentityToken

    [Authentication]: Request failed: 401, {"title":"PERMISSION_DENIED","detail":"validation failed","details":[],"status":401}

    G) AuthenticationService.Instance.LinkWithAppleAsync(idToken)

    I've tried variations on the E-G sequence but they all fail after step D.
     
  2. unity_Ctri

    unity_Ctri

    Unity Technologies

    Joined:
    Oct 20, 2020
    Posts:
    81
    Hey Mhardy,

    I'll check in with the developers, but in my own experience integrating with Facebook (and it's the same Unity endpoint that receives the external login flow), I sent the token without base64 encoding it.

    The linking process does as you expect, allows you to log back into an anonymous account from a different device. If, as you say, the user tries to link / log-in to account A (via apple) whilst playing a new save on account B, then linking will fail, and logging in will switch to the saved progress.

    With regards to the sequence, I would expect you to link your Apple account to the anonymous account - otherwise you risk losing any progress associated with the anonymous account and starting afresh with the apple login.

    Will let you know what I hear from them!
     
    Last edited: Jan 25, 2022
  3. unity_Ctri

    unity_Ctri

    Unity Technologies

    Joined:
    Oct 20, 2020
    Posts:
    81
    One piece of information I found in our bug tracker is that the documentation is a little misleading at the moment.
    Whilst it calls for the application ID, what Apple label as the app ID and what the configuration expects are slightly different.

    The value the service expects is actually what's labeled as the bundle ID, can you put that in (or confirm that it's present) and let me know how you get on? It should take the form "com.organisationname.applicationname"

    We intend to update the documentation to reflect this :)
     
  4. mahdik_unity

    mahdik_unity

    Unity Technologies

    Joined:
    Sep 16, 2021
    Posts:
    15
    Hi @mhardy ,
    as @unity_Ctri said, the idToken given shouldn't be encoded to a base64 string, instead you can use UTF8 Encoding GetString() to get the idToken you need.
    here's an example: (replace the IAppleIDCredential with your credential var name)
    Code (CSharp):
    1. var idToken = Encoding.UTF8.GetString(IAppleIDCredential.IdentityToken,0, IAppleIDCredential.IdentityToken.Length);
    Also, I would use link as Ctri said based on your authentication flow to avoid loss of progress on the anonymous account.
     
    unity_Ctri likes this.
  5. mhardy

    mhardy

    Joined:
    Apr 3, 2011
    Posts:
    48
    Success! UTF8.GetString() was the key, thanks!

    And to follow up for others, the PlayerId does change after you successfullly SignInWithApple to the PlayerId that was previously linked.
     
  6. mahdik_unity

    mahdik_unity

    Unity Technologies

    Joined:
    Sep 16, 2021
    Posts:
    15
    Glad it worked for you,
    Let me know if you have any other questions

    I would appreciate if you fill out this Survey so that we could gather feedback on the product and see what's missing to serve you better :)
     
  7. mhardy

    mhardy

    Joined:
    Apr 3, 2011
    Posts:
    48
    More than happy to! Done. Thanks again.
     
    mahdik_unity likes this.
  8. mhardy

    mhardy

    Joined:
    Apr 3, 2011
    Posts:
    48
    Do you have an answer to #3? How do we properly determine if they've already linked their account so we can take appropriate action? Other that relying on catching an exception.
     
  9. mahdik_unity

    mahdik_unity

    Unity Technologies

    Joined:
    Sep 16, 2021
    Posts:
    15
    For now, there's no other way to check for it.
    But we will consider such a feature, for sure. Feel free to suggest any feature that might be helpful to you in the survey :)
     
  10. mhardy

    mhardy

    Joined:
    Apr 3, 2011
    Posts:
    48
    I'm getting PERMISSION_DENIED again, but now with "token is expired". How do I get a new, valid, IdToken? I've tried all the methods in the 'Sign in with Apple' Plugin, but they all cause the native Sign In dialog to appear. How do I SignInWithAppleAsync() again silently after some time has passed?
     
  11. mhardy

    mhardy

    Joined:
    Apr 3, 2011
    Posts:
    48
    Any word on this? I'm still getting "token is expired" if my IdToken is a few days old. How do I get a new one?
     
  12. erickb_unity

    erickb_unity

    Unity Technologies

    Joined:
    Sep 1, 2021
    Posts:
    92
    Hey,

    I'm not sure Sign in with apple feature provides a silent sign-in that can provide the token. Are you able to retrieve the token with the popup?

    As for your flow, you could use SignInWithApple once when you need to retrieve your account and then use the anonymous login to continue using this account if you want less friction from the SignInWithApple popup.
     
  13. mhardy

    mhardy

    Joined:
    Apr 3, 2011
    Posts:
    48
    Oh I see. Yes, I get the token from the popup, then store it, and Link & SignInWithApple(idToken) just fine using it. Then continue to SignInWithApple during each login with that idToken. But I think that's the problem.

    So LinkWithAppleAsync(idToken) and SignInWithAppleAsync(idToken) are mutually exclusive. If you start with an anonymous account you only need to LinkWithAppleAsync with the idToken once, then continue to use SignInAnonymouslyAsync.

    So if moving from anonymous to an apple account, you'll actually never use SignInWithAppleAsync, is that correct?

    Thanks!
     
  14. erickb_unity

    erickb_unity

    Unity Technologies

    Joined:
    Sep 1, 2021
    Posts:
    92
    Hi,

    You would use SignInWithAppleAsync to recover an account if a player was to reinstall the game and would want to retrieve his account.

    When you use any login method, it will update the anonymous token we use for anonymous login. So you can return to anonymous login afterwards to reduce friction.
     
  15. mhardy

    mhardy

    Joined:
    Apr 3, 2011
    Posts:
    48
    Thanks for your help on this. I've reworked everything based on what you've said here and everything is working perfectly now for all scenarios and across devices.
     
    mahdik_unity likes this.