Sign in with Apple REST API

RSS for tag

The Sign in with Apple REST API allows your app's servers to communicate with Apple’s authentication servers.

Posts under Sign in with Apple REST API tag

69 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

Empty email when turning off email forwarding (Apple sign in)
Hello there, we have implemented the Apple sign in our site, everything is working good except from two edge cases when the JWT returned by Apple sign in does not contain the user email, these cases are: When users choose Hide My Email when creating their account and later manually change their settings and turning off the email forwarding (Tested). For Apple at Work & School users. i.e. younger students may not have an email address. According to Apple docs, email could be empty for Sign in with Apple at Work & School users (Not tested). The problem is that we use the email to confirm the user authentication, but when the email is not present in the JWT, our system won't be able to find the registered user. We're currently working on a workaround for this, but we would like to confirm that these edge cases are known by apple and also ask some questions: Is it correct to say that: Turning off the email forwarding will cause that Apple's identity token (JWT) does not include the user's email address? Apple at Work & School users: is there a way to identify that someone is using this type of account? Is there any other known edge case when the email could be empty in the JWT? Thanks in advance!
1
0
592
Oct ’24
Sign in with Apple user ID after App Store transfer
Hello, Following a company split we are planning to transfer one of our apps, which has Sign in With Apple enabled, to another team. We want to provide a smooth migration experience for the users by minimizing downtime and avoiding the duplication of accounts in our database. In our backend we generate a client secret using the transferring team’s ID. We then use this client secret with the “https://appleid.apple.com/auth/token” endpoint which returns the identity token. With the above in mind, I have the following questions: If we don’t update the team ID immediately after the transfer in our backend, will the identity token returned by the endpoint above contain the transferring team user ID in the sub field or, will it contain the recipient team user ID? Is there any possibility that we will ever receive an identity token containing a transferring team user ID in the sub field after we accept the transfer? Thanks, Bruno
1
0
555
Oct ’24
Sign-In with Apple App Transfer and User Migration
Hi all, I am in the process of preparing for an app transfer, and have sign-in with apple enabled. I have read the documentation thoroughly and multiple times, yet there are a few things I'd like to have a confirmation about, before taking the leap and risking that some users might experience any issues. If I understand correctly, after the migration if a user performs a sign-in with Apple, they will send an access_token that differs from the one they were sending when the app was assigned to the old team. In case I didn't take any action that means that my system would think this was a new user given the access_token has never been seen before, and therefore it will create a new user. Is that correct? Ok, so if that assumption is correct, I'd like to have a confirmation also of the way I intend to fix this, since we're doing an internal transfer and the database is going to be the same. I would get a TransferID for all users in my database that have used sign-in with Apple (I have already done that for one of my test users, successfully). After that, I will start the transfer, and accept it from the other team. Once that is done, I will call the migrationinfo endpoint from the other team, getting all the new access_tokens related to the transfer ids. With that information, I will update my databse, adding a relation from the new access token from team B that points to the same user as the access token that was given by team A, and I know which one it is because of the TransferID. Does that make sense? Would it work? I'm not a fan of messing with the login logic (having a look at transfer_ids, looking for matches, and so on), especially because there doesn't seem to be a way to test this. I believe the only risk is that a user might login after the app has been transferred but before I can upload the new access token to the database, but we can handle these (few, hopefully even zero cases) via ticketing. These are the resources I have read so far: https://developer.apple.com/documentation/technotes/tn3159-migrating-sign-in-with-apple-users-for-an-app-transfer#Preparing-to-migrate-users-for-an-app-transfer https://developer.apple.com/documentation/sign_in_with_apple/transferring_your_apps_and_users_to_another_team#3546291 https://developer.apple.com/documentation/sign_in_with_apple/bringing_new_apps_and_users_into_your_team My last question is: how can I test this before going live? Do I really have to just implement changes/update the DB and then go live, hoping that it will all work? Can't I do some sandbox transfer or anything like that? Even just creating like a "clone" of my app and transferring this one would be a huge boost for the confidence of this big leap. Thanks in advance.
4
0
1.6k
Sep ’24
App transfer - failed to retrieve info after app transfer
Hi! Like a bunch of people on the forums I'm having issues transferring my users from my previous Team to my new Team. When the app was still on the old team, I successfully generated transfer_subs for every one of my apple login users. Now, when trying to migrate them over, it ONLY works on users that have already signed in since the transfer, which is not good, I need to transfer the rest and get the new private relay emails. Here’s a curl of how I get my access token : I’m first generating the secret key using my team key that has apple sign in configured for it. curl --location 'https://appleid.apple.com/auth/token' --header 'Content-Type: application/x-www-form-urlencoded' --data-urlencode 'grant_type=client_credentials' --data-urlencode 'scope=user.migration' --data-urlencode 'client_id=my.app.id' --data-urlencode 'client_secret=*** This works and I’m getting my access token, then I try to exchange the sub token curl --location 'https://appleid.apple.com/auth/usermigrationinfo' --header 'Content-Type: application/x-www-form-urlencoded' --header 'Authorization: Bearer *** ' --data-urlencode 'transfer_sub=xx.xxxx' --data-urlencode 'client_id=my.app.id' --data-urlencode 'client_secret=***’ This is when I receive : {"error":"invalid_request","email_verified":false} I’ve tried a lot of stuff, even got on the phone with an ex apple engineer and tried a bunch of stuff with him, but to no avail. I've submitted a report on feedback assistant on the 23rd August, but no answer yet. ID: 14898085
1
0
610
Sep ’24
Encountering invalid_client error when calling Apple authentication/revocation API
Hello, I have implemented Sign in with Apple in my iOS app and am currently trying to implement the revocation feature. However, I keep encountering an invalid_client error when calling the Apple authentication/revocation API. Here are the details of my configuration: Team ID: HUGD2H952H Client ID: com.puppylink.puppylinkapp Key ID: KXSYK98424 I am using these details to generate a client secret with the JWT ES256 algorithm. Below is the code I am using on the backend server to generate the client secret: private fun makeClientSecret(): String { val now: ZonedDateTime = ZonedDateTime.now(ZoneOffset.UTC) val expirationTime: ZonedDateTime = now.plusMinutes(5) // Setting expiration time to 5 minutes return Jwts.builder() .setHeaderParam(JwsHeader.KEY_ID, appleProperties.keyId) .setHeaderParam("alg", "ES256") .setIssuer(appleProperties.teamId) .setIssuedAt(Date.from(now.toInstant())) .setExpiration(Date.from(expirationTime.toInstant())) .setAudience("https://appleid.apple.com") .setSubject(appleProperties.clientId) .signWith(getPrivateKey(), SignatureAlgorithm.ES256) .compact() } private fun getPrivateKey(): PrivateKey { val resource = ClassPathResource(appleProperties.privateKeyFile) val privateKey = String(Files.readAllBytes(Paths.get(resource.uri))) val pemReader: Reader = StringReader(privateKey) val pemParser = PEMParser(pemReader) val converter = JcaPEMKeyConverter() val keyInfo = pemParser.readObject() as PrivateKeyInfo return converter.getPrivateKey(keyInfo) } } Additionally, here is the code used to call the Apple authentication API from the backend server: @Service class AppleAuthService( private val appleProperties: AppleProperties, ) { private val logger = LoggerFactory.getLogger(javaClass) private val restTemplate = RestTemplate() fun getTokens(authorizationCode: String): TokenResponse { try { val clientSecret = makeClientSecret() val formData: MultiValueMap<String, String> = LinkedMultiValueMap() formData.add("client_id", appleProperties.clientId) formData.add("client_secret", clientSecret) formData.add("code", authorizationCode) formData.add("grant_type", "authorization_code") val headers = HttpHeaders() headers.contentType = MediaType.APPLICATION_FORM_URLENCODED val requestEntity = HttpEntity(formData, headers) val response = restTemplate.postForObject( "https://appleid.apple.com/auth/token", requestEntity, TokenResponse::class.java, ) return response ?: throw RuntimeException("Failed to retrieve tokens from Apple") } catch (ex: Exception) { logger.error("Error retrieving tokens: ", ex) throw ex } } data class TokenResponse( val access_token: String, val expires_in: Long, val id_token: String, val refresh_token: String, val token_type: String, ) Despite generating the client secret correctly, I am still receiving the invalid_client error when calling the API. Could you please help me identify the cause of this error and provide guidance on how to resolve it? Thank you.
1
0
645
Sep ’24
Sign Up & Sign In With apple
For Sign in With Apple I recieve an expected flow including an ask to share or hide my email along with a message like this 'Create an account for Apple {some_company} using your Apple ID “{email}”.' However when i sign into an existing account i get the same flow, where on other apps i see a message like this ~ "Do you want to continue using {some_company} with your Apple ID “{email}”? How can i configure this for my own app? Note: it always logs me into the correct existing account, i'm just trying to make sure users go through the correct flow in the apple popup when their account already exists.
2
1
957
Sep ’24
Migrating "Sign in with Apple" users
We are currently using "Sign in with Apple for the web": https://developer.apple.com/help/account/configure-app-capabilities/configure-sign-in-with-apple-for-the-web/ but we do not publish apps on the App Store. Because of corporate re-structuring, we need to migrate to a new Apple Developer / App Store Connect account. So we are looking to migrate "Sign in with Apple" users to the new account. Apple does provide guides on how to do it: https://developer.apple.com/documentation/technotes/tn3159-migrating-sign-in-with-apple-users-for-an-app-transfer but unfortunately, it only works if "Sign in with Apple" is used with an app published on the App Store (it requires app transfer). Who should we handle this case? Please help.
1
0
829
Sep ’24
Sign In With Apple on IPhone
Hello there, I have been facing an issue with apple sign in on react native app. I have been able to get the authorization and all codes in frontend part. The issue is on backend that is in php. We are firstly validating our identity token phone generated, and then we are creating a client secret and then trying to fetch the user info the issue relies in the api call of getAppleUser($authorizationCode, $clientId, $clientSecret);: function below where we are recieving error like: {"error":"invalid_grant","error_description":"client_id mismatch. The code was not issued to com.marchup.prod.AppSSO."} public function appleAuth($identityToken,$authorizationCode) { if (!$identityToken || !$authorizationCode) { return $this->returnError(400,'Missing identity token or authorization code'); } try { // Validate identity token $decodedToken = $this->validateAppleToken($identityToken); // Generate client secret $teamId = isset(Yii::$app->params['apple-auth']['teamId'])?Yii::$app->params['apple-auth']['teamId']:''; $clientId = isset(Yii::$app->params['apple-auth']['clientId'])?Yii::$app->params['apple-auth']['clientId']:''; $keyId = isset(Yii::$app->params['apple-auth']['keyId'])?Yii::$app->params['apple-auth']['keyId']:''; $privateKey = isset(Yii::$app->params['apple-auth']['privateKey'])?Yii::$app->params['apple-auth']['privateKey']:''; $clientSecret = $this->generateClientSecret($teamId, $clientId, $keyId, $privateKey); // Get user info from Apple $appleUser = $this->getAppleUser($authorizationCode, $clientId, $clientSecret); // Verify the authorization code is valid if (!isset($appleUser['id_token'])) { throw new \Exception('Invalid authorization code'); } // Extract user info from the identity token $userId = $decodedToken->sub; $email = $decodedToken->email ?? ''; // login or signup code need to know about object definition to add login and signup logic return $this->returnSuccess('Request successful',200,[ 'userId' => $userId, 'email' => $email ]); } catch (\Exception $e) { // Handle errors Yii::error('Error on apple login '.$e->getMessage()); return $this->returnError(500,'Server Error'); } } **This function is where i am creating a clientSecret as per apples guidelines: ** function createClientSecret($teamId, $clientId, $keyId, $privateKey) { // $key = file_get_contents($privateKeyPath); $key=$privateKey; $headers = [ 'kid' => $keyId, 'alg' => 'ES256' ]; $claims = [ 'iss' => $teamId, 'iat' => time(), 'exp' => time() + 86400 * 180, 'aud' => 'https://appleid.apple.com', 'sub' => $clientId ]; return JWT::encode($claims, $key, 'ES256', $headers['kid']); } **This is the validate Apple Token that is not giving me error: ** function validateAppleToken($identityToken) { $client = new Client(); $response = $client->get('https://appleid.apple.com/auth/keys'); $keys = json_decode($response->getBody(), true)['keys']; $header = JWT::urlsafeB64Decode(explode('.', $identityToken)[0]); $headerData = json_decode($header, true); $kid = $headerData['kid']; $publicKey = null; foreach ($keys as $key) { if ($key['kid'] === $kid) { $publicKey = JWK::parseKey($key); break; } } if (!$publicKey) { throw new \Exception('Public key not found'); } try { $decoded = JWT::decode($identityToken, $publicKey, ['RS256']); return $decoded; } catch (\Exception $e) { throw new \Exception('Token validation failed: ' . $e->getMessage()); } } The response i got was : { aud: "com.abc" auth_time: 1718017883 c_hash: "HSNFJSBdut5vk84QyK0xHA" exp: 1718104283 iat: 1718017883 iss: "https://appleid.apple.com" nonce:"2878cd1ac1fa121f75250f453edaac47365f5144f2e605e8b526a29cb62c83da" nonce_supported: true sub: "001703.2a52ec72cb874a93986522fa35742bd4.1219" } After that we are mainly getting error as {"error":"invalid_grant","error_description":"client_id mismatch. The code was not issued to com.marchup.prod.AppSSO."} in this function: function getAppleUser($authorizationCode, $clientId, $clientSecret) { try { $client = new Client(); $response = $client->post('https://appleid.apple.com/auth/token', [ 'form_params' => [ 'client_id' => $clientId, 'client_secret' => $clientSecret, 'code' => $authorizationCode, 'grant_type' => 'authorization_code' ] ]); if ($response->getStatusCode() !== 200) { throw new \Exception('Failed to get user information from Apple. Status code: ' . $response->getStatusCode()); } $data = json_decode($response->getBody(), true); // Check if the response contains the expected data if (!isset($data['access_token']) || !isset($data['id_token'])) { throw new \Exception('Invalid response from Apple. Missing access token or ID token.'); } // Return the decoded data return $data; } catch (\Exception $e) { // Log any other unexpected errors Yii::error('Unexpected error: ' . $e->getMessage()); // Re-throw the exception to propagate it further throw $e; } } Assumptions: bundleId = com.marchup serviceId i created as client_id= com.marchup.prod.AppSSO team ID= as usual keyId= is the id i created in apple developer consonsole. And the private key is the key inside the private key file. Can anyone please answer. What is mismatched here
1
0
747
Oct ’24
Issue with Sign in with Apple Token Revocation API
Hello everyone! I'm encountering an issue while trying to use the Sign in with Apple token revocation API. I've followed the steps outlined in the official documentation (https://developer.apple.com/documentation/sign_in_with_apple/revoke_tokens), but when I consume the API, I receive a 200 status code instead of the expected code. I've double-checked my implementation and can't find any obvious errors. Has anyone else experienced this issue before? I would greatly appreciate any suggestions or advice on how to resolve this issue. Thank you in advance for your help!
2
0
642
Nov ’24
Sign in with Apple Revocation goes through but ineffective? Radar time?
Good day folks, We have a workflow setup where a new Sign in with Apple user registers (first SIWA login where user can pick name and show/hide email), and the server-side code obtains a refresh token from SIWA REST API. That refresh token is stored internally against the user's profile in the DB for future use. Whenever user account is deleted from server-side, we use that refresh token to revoke Sign in with Apple (so that the user would need to go through registration flow rather than sign in- where they have an option to specify name and show/hide email). That has been working beautifully until we have added an AppClip to the app. The code which obtains the refresh token "respects" the correct bundle ID for the main app / app clip, and everything seems to work. Both of Apple's APIs return OK codes. In fact, we even get the email from Apple when token is revoked which reads "APP_NAME has revoked your Sign in with Apple account. Next time you use Sign in with Apple to sign in to your onUgo Access account, you will have to share your name and email again". Problem is- it doesn't. SIWA still offers to "sign in" as if account is still linked, and the app still shows up as "App using Sign in with Apple" in iPhone settings. What's even more mysterious is that you can't delete/revoke/"Stop using Apple ID" on that SIWA link with the app from iPhone settings too! It seems to work, but the app never goes away from the list, as if it fails silently. Could anyone please help shed some light on this?
1
1
1.1k
Oct ’24
Configuring Sign in with Apple for web and mobile apps
Summary: Need help with Certificates, Identifiers and Profiles settings to allow two apps to use Sign in with Apple. Background: We have a web application (React, static JavaScript) that allows users to sign in with Apple, Google or Microsoft via OAuth/OIDC. We are developing a mobile application using React Native and Expo. Both the web application and the mobile application use the same backend (Django). For the mobile application, we added Google and Microsoft sign in via the same web-based OAuth/OIDC flow. For Sign in with Apple, we are using the expo-apple-authentication package to get the required native sign in experience. We have two active app identifiers: org.terraso.terraso; web app; primary Apple ID org.terraso.test.Terraso-LandPKS; mobile apple; Group with an existing primary App ID (selected (1), the web app) We have one services identifier: org.terraso.app; primary ID is web app (app identifier 1) above; URLs have been configured We have one app group: group.org.terraso (seems unused) On our backend app, we have code: https://github.com/techmatters/terraso-backend/blob/abc655e83eaca849e2bc24389946cc4f0bcd9d48/terraso_backend/apps/auth/providers.py#L84 and APPLE_CLIENT_ID is set to org.terraso.app (which matches the services identifier above In my local development environment, I have tried a few different combinations of IDs attempting to get this to work using the iOS simulator: (i) backend client id: org.terraso.app mobile app bundle Id: org.terraso.test.Terraso-LandPKS result: error: jwt.exceptions.InvalidAudienceError: Audience doesn't match (ii) backend: org.terraso.app mobile app: org.terraso.app result: clicking "Sign In" in Apple ID dialog is a no-op (no errors from client or server) (iii) backend: org.terraso.test.Terraso-LandPKS mobile app: org.terraso.test.Terraso-LandPKS result: works (but I can't use that in production, because the client ID is wrong) How can I configure Sign in with Apple to allow both the web app, the mobile app (and possible additional mobile apps) to work with the same backend? Do I need to us app groups? When do you use app groups vs "group with an existing primary apple id"?
0
1
1.7k
Oct ’24
Apple Sign-In: transfer an app twice in a row
When transferring an app from one team to another, Sign in with Apple users have to me carefuly migrated since their unique identifiers are team-scoped. To migrate users from Team A to Team B, a transient transfer identifier, aka transfer_sub, has to be generated by Team A before the transfer to prepare the app data, using specific migration endpoints provided by Apple. "Preparing the app data" means, for example, associate database entries to the transfer id instead of the team-specific id. One the app has been transferred, and during 60 days, Team B will find the transfer_sub in ID tokens issued by Apple Sign In, and thanks to this shared identifier they can retrieve the user data and associate it to their new unique identifier. So far so good ! Now, the question : if an app is transferred from Team A to Team B, and then, shortly thereafter (a few days later), from team B to team C, will the transfer_sub related to the B-C transfer be different ? Or will they remain the same as the ones issued for the A-B transfer ? (I'm asking this question in order to avoid the possible catastrophe of an ill-prepared double app transfer) Thank you !
1
1
977
Sep ’24
Email is returned only once
We are implementing Sign Up with Apple ID and facing the following issue: Email is returned only on the first response. All subsequent responses for this user do not return email. But our system is email-driven. So, if user first signs up on our TST environment then we will not be able to Sign up this user on UAT and Prod without an email in response. Could anyone please advise how to approach this problem.
1
0
861
Nov ’24
Login issue with socialiteproviders in laravel
Hi all, I create web app laravel with function login with apple. This is any my information app and packet what i'm use : Laravel: 10.x PHP: 8.1 Packages for login: https://socialiteproviders.com/ I'm done with API appleid.apple.com/auth/authorize for auth user with apple ID. Response below : So next step i call to this API : https://appleid.apple.com/auth/token for verify token but response is below : I'm try with postman but response is same that ( invalid_client ). Everything is correct( client_id, team_id, private_key ). I use https://jwt.io/#debugger for test verify token. Signature Verified is result. Can help me for declare what is issue ? what client is invalid ? Thank you so much. P/s : Sorry for my poor English
1
0
2.3k
Sep ’24
Apple Sing In on VisionOS
Hello. On my game I have Apple Sing In option that is required to keep user high score, show name in game, and for other app functionality. Game is made on Unity. Now when I'm trying to port the game to Vision Pro, Im getting error that Authentication is not supported on this platform. It may be the plugin issue that I'm using(not sure yet). But I also didn't find any documentation for native code ( so I could make plugin that unity game could use). Question: does VisionOS support Apple Sing In in the applications? if yes please give me some resources. if no - is there any plans to add that functionality? Thanks.
1
0
738
Nov ’24
Even when calling the Apple Login Revoke API, the app still remains in the user's account.
Problem Situation User membership withdrawal request → revoke API call It always returns status code 200, but once out of 5~10, it remains an app linked to the user's Apple ID. Re-request user Apple login → Email is returned as null Currently, the only solution is for users to manually delete apps linked to their Apple ID. Email sent when re-requesting Apple login When the above problem occurs, even if the Revoke API is called multiple times, the app linked to the user's Apple ID is not deleted, and when requesting Refresh Token validation, it has already expired. Releated Issues https://forums.developer.apple.com/forums/thread/707181
1
0
857
Nov ’24
Email is not included in id_token
We have a game that provides a mechanism to log into the game with Sign in with Apple in a direct integration between the game and Apple (first mechanism). We also provide a mechanism to log into the game using OpenID connect with authorization from Apple but using a server in the middle that drives the process (second mechanism). It is important to mention that both mechanisms use the same oauth client. We have been able to switch from the first mechanism to the second successfully, but there is a problem with id_token. In the second mechanism we request the scopes "email", "openid" and "name", but in the retrieved id_token there is no information about the email. It happens for all users who previously signed in with Apple using the first mechanism (therefore there is a current link between the game and the user in AppleId). It does not happen with users who had no link between the game and the user and use the second mechanism, in this case we can retrieve the user information in the callback of the first call and the email in the id_token, as stated in the documentation. However, if users who had a link between the game and the AppleId delete the app and then log back in using the second mechanism, then we can get the email information with the exact same request. The request we use to obtain the authorized endpoint information (https://appleid.apple.com/auth/authorize) has these parameters: response_mode: query scope: email openid profile nonce: ... state: ... response_type: code Then we get the authentication code and get an id_token like this: { "iss":"https://appleid.apple.com", "aud":"{aud}", "exp":1705584621, "iat":1705498221, "sub":"{sub}", "nonce":"7f-PqBoXgxeDMOEu5Ysov0FjE9GvSYfq", "at_hash":"3kLcPBlwZP6aj_mscww5zA", "authentication_time":1705498218, "nonce_supported":true } Is there a way to retrieve the email for users who had the link and don't want to delete it or log back into the app? In the official Apple documentation it is stated that the id_token should have the email but this is not the case. https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_rest_api/authenticating_users_with_sign_in_with_apple#3383773
2
2
1.5k
Nov ’24