What the Heck is Sign In with Apple?

Dj Dance

it’s most important comment ever. Thanks!

BalintFarago

Great tutorial, but how are we supposed to get the user’s information? After the user is redirected to the redirect uri such as https://mywebsite.com/Apple…, there isn’t any information in the URL.

BalintFarago

How can I get the user’s first name and last name? This tutorial easily ignores it, while considering Apple sends it only the first time the user logs in, there is literally no information about that on the internet. How do I extract it from the response and how does the response looks like the first time the users logs in?

BalintFarago

Found it out: user is a POST variable like code or state.

$json = $_POST[“user”];
$obj= json_decode($json);
$firstname = $obj->name->firstName;
$lastname = $obj->name->lastName;
$emailaddress = $obj->email;

Andy G

This was so, so helpful; it’s the only decent guide out there. (Apple’s own docs certainly aren’t.)

Something that was helpful for me, and might be helpful for others (particularly those working in languages other than Ruby, who can’t simply follow Aaron’s code exactly) - JWT.io has a handy debugger that allows you to paste in your JWT and see the decoded result. Handy for discovering stupid mistakes like, for example, you’re passing the iat and exp times in as milliseconds, rather than seconds.

Harrison

Hi. I keep getting this syntax error on the client_secret.rb file

client_secret.rb:1: syntax error, unexpected backslash, expecting '}'

any help? thanks

Robert

Thanks a lot! I got very far, but I did not receive any data with $_POST[‘code’] after the user was logged in and sent back. I found a solution at https://developer.apple.com…. So change the response_mode’ => 'query and delete ‘scope’ => ‘name email’. Then, use $_GET instead, to read the code. Unfortunately, I still can not get the firstName and lastName. Any clues?

imn2

This is very helpful. Thanks so much!

I believe there may be some confusion in here. The “state” field is used for transmitting key/value, boolean, etc. info to Apple, which will come back to your server when Apple calls your server back. A classical example of useful state to send and then later receive back would be the “stay logged in” boolean state. This state is related to the attempt to authenticate itself, and makes most sense to be able to recover this state as the authentication process moves forward, without need to persist state in a DB on the server.

I think you may be talking about the “nonce” field, which is used for preventing replay attacks, not CSRF. This field should be set to some random value, and that random value should be checked against the nonce field in the auth response.

All this said, I have not used Apple Sign In yet. But from having done OAuth in Google-land and used state fields to transmit such state as “stay logged in”, and having used nonces in cryptography, I think your writeup might be improvable.

Further, I am not totally certain why Apple needs this nonce. This may be because Apple does not assume that auth travels only over TLS/SSL. Apple’s response is always over TLS/SSL, but I don’t see the requirement that the server itself initiates auth over TLS/SSL. That may be why the nonce is necessary, to ensure that multiple auth initiations from the same user do not generate the same locally encrypted string. That would be vulnerable to attack. I would think that if you are actually initiating auth over TLS/SSL, then creating and/or checking the nonce is unnecessary… but I don’t know Apple’s implementation details on this, so be careful :wink:

imn2

bravo. i am about to try this.

TimHaynes

Just a note that the Return Url must be entirely in lowercase. I ran into problems when I naively included a mix of upper and lowercase in the Return URL (“invalid redirect” error).

James

I recently implemented Sign In with Apple in Laravel.

I wrote a blog post on generating the client secret/JWT for each request so that you never need to worry about the client secret expiring (as per this Okta post, it expires after 6 months). If you’re interested, here is the post explaining how I did it

max

in php
https://github.com/gradus0/…

Is it possible to get an access token using auth code when the user signs in a second time? I’m always getting errors when trying to get accessToken however if I revoke the app manually by going into settings->password&securtiy->Apps Using Apple Id section. Then after this, If I get an access token I’m able to get it but with the same code, if I try a second time after 10 minutes using a new authorization code I get an error (invalid_grant). Does anyone know what is wrong with the apple auth token API?

Sadly Apple made some pretty bizarre decisions in their OAuth/OIDC implementation and there’s no way around this as far as I can tell.

Thanks for your reply. Actually, apple made a new requirement for revoke tokens so in the beginning when I added sign-in with apple I just used a user identifier and I never stored refresh/access tokens. Now I’m not able to get a refresh access token even If am making users do sign-in flow again. I’m really stuck at this point :frowning: