skip to Main Content

I’m a bit confused to how all this works.

I’ve implemented Sign In with Apple in my native iOS app, I do save all info Apple provides once the login success, like IdentityToken, UserId, and authorization code.

Already reviewed and we have to implement the Revoke Tokens API endpoint using the Sign in with Apple REST API Revoke Tokens just that I don’t have clear which the client_id, what is the client_secret, and what is the token.

As per my understanding.

Is client_id the bundle ID right?
Is client_secret the identityToken provided by Apple during the Sign In process?.. I just stored and share this token to our server but getting the invalid_client error

I’d really appreciate it if someone can explain what should I do with the info provided during Sign in with Apple flow (UserId, IdentityToken, and AuthorizationCode) in order to properly implement the Revoke Tokens API.

2

Answers


  1. Chosen as BEST ANSWER

    After doing a bit of research and spending a few hours, understand the flow.

    Just a note that in my case I’ve implemented the apple sign-in option in the native iOS app.

    Here are the three important steps that need to be followed to revoke the token.

    1. Get authorizationCode from Apple login (client side).
    2. Get a refresh token or access token with no expiry time using authorizationCode through authtoken (server side).
    3. Revoke the refresh token or access token through tokenrevoke (server side).

    Client Side(App side):

    1. Get authorizationCode from Apple login.
    • After sucessfully login in app you will get authorization code from the apple native didCompleteWithAuthorization delegate call.

    • When you receive the authorization code you will need to send the code to the server immediately, as the code is one use only and valid for five minutes.

       func authorizationController(controller: ASAuthorizationController,
      didCompleteWithAuthorization authorization: ASAuthorization) {
      
         if let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential {
           let authorizationCode = String(data: appleIDCredential.authorizationCode!, encoding: .utf8)!
         }
       }
      

    Server side (backend side):

    1. Get a refresh token or access token with no expiry time using
    • Once received authorization code from the client side, You will need to validate this code via authtoken.

    • When you send an authorization request to the validation server(Apple server), include the following form data parameters.

    • client_id = "com.demo.app" (your app bundle id)

    • client_secret = A secret JSON Web Token, generated by the developer, that uses the Sign in with Apple private key associated with your developer account.

    • code = The authorization code received in an authorization response sent to your app

    • Important: Create the client secret (client_secret) GET REFERENCE FROM THE APPLE DEVELOPER DOCUMENTATION.

      • JSON Web Token (JWT) is an open-standard (RFC 7519) that defines a way to transmit information securely. Sign in with Apple requires JWTs to authorize each validation request. Create the token, then sign it with the private key you downloaded from Apple Developer.

      • To generate a signed JWT:

          1. Create the JWT header.
          1. Create the JWT payload.
          1. Sign the JWT.
      • To create a JWT, use the following fields and values in the JWT header:

      alg --> The algorithm used to sign the token. For Sign in with Apple, use ES256.

      kid --> A 10-character key identifier generated for the Sign in with Apple private key associated with your developer account.

      • The JWT payload contains information specific to the Sign in with Apple REST API and the client app, such as issuer, subject, and expiration time. Use the following claims in the payload:

      is --> Use your 10-character Team ID associated with your developer account.

      iat --> The issued at registered claim indicates the time at which you generated the client secret, in terms of the number of seconds since Epoch, in UTC.

      exp --> The expiration time registered claim identifies the time on or after which the client secret expires. The value must not be greater than 15777000 (6 months in seconds) from the Current UNIX Time on the server.

      aud --> https://appleid.apple.com.

      sub --> Use the same value as client_id. The value is case-sensitive.(app bundle id).

    • After creating the JWT, sign it using the Elliptic Curve Digital Signature Algorithm (ECDSA) with the P-256 curve and the SHA-256 hash algorithm. A decoded client_secret JWT token has the following format:

       {
         "alg": "ES256",
         "kid": "AEBD123DEPG"
       }
      
       { 
         "iss": "EED153GJIJ",
         "iat": 1437179036,
         "exp": 1493298100,
         "aud": "https://appleid.apple.com",
         "sub": "com.demo.app"
       }
      
    • After the server validates the refresh token, the endpoint returns the identity token and an access token. The following is an example refresh token validation response:

       {
         "access_token": "beg3456...67Or9",
         "token_type": "Bearer",
         "expires_in": 3600,
         "id_token": "eyPgkk...96sZg"
       }
      

    Revoke the refresh token or access token through tokenrevoke (server side).

    • In order to revoke authorization for a user, you must obtain a valid refresh token or access token that you get in step (2).

    • Once you have a valid refresh or access_token you will be able to revoke the token via tokenrevoke end point.

    • There are below parameters required for the server to invalidate the token.

    • client_id = "com.demo.app" (your app bundle id)

    • client_secret = "A secret JSON Web Token same way you generate in the step 2".

    • token = access_token which is what you get from the step 2 end point call.

    Once the access token revokes client side gets a notification for the same, for that client needs to add the below the observer.

    func addObserverforRevokeAppleSignToken() {
      let sessionNotificationName = ASAuthorizationAppleIDProvider.credentialRevokedNotification
      NotificationCenter.default.addObserver(forName: sessionNotificationName, object: nil, queue: nil) { (notification: Notification) in
        // Sign user out
        print("Apple sign in token revoked....")
      }
    }
    

    You can check Settings - Password & Security > Apps Using Apple ID.

    Thank you.


  2. Based on the documentation Revoke Tokens:

    • client_id – The identifier (App ID or Services ID) for your app.
    • client_secret – A secret JSON Web Token (JWT) that uses the Sign in with Apple private key associated with your developer account. For more information about creating client secrets, see Generate and validate tokens.
    • token – The user refresh token or access token intended to be revoked. The user session associated with the token provided is revoked if the request is successful.

    client_id

    I am not 100% sure, but it worth trying the following:

    1. Go to https://appstoreconnect.apple.com
    2. Select My Apps
    3. Select your app
    4. On the Sidebar select App Information
    5. You will see Apple ID (10 digit numeric id)

    Try using this 10 digit id as your client_id

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search