apple-auth

repository·master·Indexed 43 days ago

https://github.com/ananay/apple-auth

A Node.js library for simplifying the 'Sign in with Apple' authentication flow. Version 1.1.0 provides methods to generate login URLs, exchange grant codes for access tokens, refresh tokens, and revoke tokens. It includes the AppleClientSecret class for generating ES256 signed JWT client secrets and supports fetching user names and emails.

Tokens
3.7K
Snippets
17
Records
21
Agent score
72%

What's inside apple-auth

  1. Important: Handling User Name and Email

    master

    Data Persistence Requirement

    Apple provides the user's name only once: during the very first time the user taps "Sign in with Apple" in your application.

    You must store the name in your database immediately during this first interaction.

    For all subsequent logins, Apple will only provide a unique ID and the user's email. You should use these to look up the existing user in your database.

  2. Configure Apple Developer Account for Sign in with Apple

    master

    To use this library, you must configure several identifiers in your Apple Developer account. This involves three main steps:

    1. Create an App ID: Even if you do not have a native iOS or Mac app, you must create an App ID. Ensure that the "Sign in with Apple" capability is checked under the "Capabilities" section.
    2. Create a Services ID: This acts as your client_id. During setup, click "configure" on "Sign in with Apple", add your domain in the "Domains" section, and specify your allowed redirect URL. You must verify your domain using the download and verify buttons provided in the Service ID configuration.
    3. Create a Key: Go to the "Keys" section and create a new key. Configure it to assign "Sign in with Apple" to your specific App ID. Important: Download the private key file immediately and store it securely; you cannot download it again once it is gone.
  3. Configure the apple-auth library using config.json

    master

    The library requires a config directory containing your downloaded private key file and a config.json file. The config.json file must contain the following fields:

    • client_id: The "Service ID" created in the Apple Identifiers section.
    • team_id: The 10-character code found at the top left of your Apple Developer page.
    • redirect_uri: The return URL you registered in the Apple Developer portal.
    • key_id: The identifier for the private key you generated.
    • scope: The information requested from the user (e.g., email and/or name).

    Note: Providing email or name in the scope ensures your app is ready for when Apple fully releases these features, preventing the need for users to re-authorize later.

    {
        "client_id": "",
        "team_id": "",
        "redirect_uri": "",
        "key_id": "",
        "scope": ""
    }
  4. Enable debug mode in AppleAuth

    master

    To troubleshoot failed requests, you can enable a debugging mode. When this mode is active, all failed requests are logged to the console, and error messages will contain more specific details. To enable it, pass an options object with the debug key set to true as the fourth argument when initializing the AppleAuth class.

    let auth = new AppleAuth(
      config,
      SECRET_KEY,
      TEXT_METHOD,
      {
        debug: true
      }
    );
  5. Use AppleAuth methods for authentication

    master

    The AppleAuth instance provides three primary methods to handle the Sign in with Apple flow:

    • auth.loginURL(): Generates the Login URL that users must visit to authenticate.
    • auth.accessToken(grantCode): Exchanges a received grantCode for an access token.
    • auth.refreshToken(refreshToken): Uses a refreshToken to obtain a new access token.
  6. Initialize AppleAuth

    master

    To use the library, instantiate the AppleAuth class. You need to provide a configuration object (loaded from a file) and the path to your .p8 authentication key file.

    const fs = require('fs');
    const AppleAuth = require('apple-auth');
    
    // Load your configuration file
    const config = fs.readFileSync("./config/config");
    
    // Initialize the auth instance with config and the path to your AuthKey.p8
    const auth = new AppleAuth(config, './config/AuthKey.p8');
  7. Generate Apple client secrets with AppleClientSecret

    master

    The AppleClientSecret class is used to generate the JWT client secret required for Apple authentication. It handles reading the private key from either a file or a raw string and signs a JWT using the ES256 algorithm.

    Constructor Parameters

    new AppleClientSecret(config, privateKeyLocation, privateKeyMethod)

    • config (object): An object containing the following keys:
      • client_id (string): Your Apple Service ID.
      • team_id (string): Your Apple Team ID.
      • redirect_uri (string): Your authorized redirect URI.
      • key_id (string): The Key ID of your private key.
    • privateKeyLocation (string): Either the file path to your .p8 private key file or the raw text of the private key itself.
    • privateKeyMethod (string, optional): Defines how to treat privateKeyLocation.
      • 'file' (default): Treats the location as a file path to be read.
      • 'text': Treats the location as the raw private key string.

    Usage

    Call the .generate() method to receive a Promise that resolves to the generated JWT token string. The token is configured to expire in 6 months.

    const AppleClientSecret = require('apple-auth/src/token'); // Adjust path as necessary
    
    const config = {
      client_id: 'com.example.service',
      team_id: 'TEAMID123',
      redirect_uri: 'https://example.com/callback',
      key_id: 'KEYID456'
    };
    
    // Option 1: Loading from a file
    const generator = new AppleClientSecret(config, './path/to/AuthKey_ABC123.p8', 'file');
    
    // Option 2: Loading from a raw string
    // const generator = new AppleClientSecret(config, '-----BEGIN PRIVATE KEY-----\n...', 'text');
    
    generator.generate()
      .then(token => console.log('Generated Token:', token))
      .catch(err => console.error('Error:', err));
  8. Refresh an expired access token

    master

    Use the refreshToken(refreshToken) method to obtain a new access token using a previously issued refresh token. This is useful for maintaining a user's session without requiring them to re-authenticate manually.

    try {
      const newTokenData = await appleAuth.refreshToken(oldRefreshToken);
      console.log('New Token Data:', newTokenData);
    } catch (error) {
      console.error(error);
    }
  9. Initialize the AppleAuth client

    master

    To use the library, instantiate the AppleAuth class. The constructor requires the AppleAuthConfig object, the file path to your private key (privateKeyLocation), the method to read the key (privateKeyMethod), and an optional CustomConfig object.

    import AppleAuth from 'apple-auth';
    
    const config = {
      client_id: 'com.example.service',
      team_id: 'TEAMID123',
      redirect_uri: 'https://example.com/callback',
      key_id: 'KEYID123',
      scope: 'name email'
    };
    
    const appleAuth = new AppleAuth(
      config, 
      './path/to/private_key.p8', 
      'file', 
      { debug: true }
    );
  10. Generate the Apple Login URL

    master

    Call loginURL() to generate the authorization URL used to redirect the user to Apple's sign-in page. This method also generates and stores a unique state value to prevent CSRF attacks. You should retrieve this state value using the state getter and verify it when the user is redirected back to your application.

    const url = appleAuth.loginURL();
    const state = appleAuth.state;
    
    // Redirect the user to 'url' and verify 'state' on callback