{"id":46974,"library":"apple-signin","title":"apple-signin","description":"Node.js wrapper around the Sign in with Apple REST API, enabling authentication with Apple accounts in Node.js applications. Current stable version is 1.0.9. The package supports generating authorization URLs, exchanging authorization codes for tokens, verifying ID tokens, and refreshing access tokens. It requires Apple Developer Program enrollment and proper configuration (Service ID, private key). Release cadence is low (last update: September 2019). Differentiators: simple API wrapping Apple's OAuth flow; limited to server-side use (no browser SDK integration). Alternatives like 'apple-auth' or 'passport-apple' may offer more features. Note: library is unmaintained; no TypeScript types; uses callbacks/promises.","status":"maintenance","version":"1.0.9","language":"javascript","source_language":"en","source_url":"git://github.com/Techofficer/node-apple-signin","tags":["javascript","apple","signin","auth","login","node","authentication"],"install":[{"cmd":"npm install apple-signin","lang":"bash","label":"npm"},{"cmd":"yarn add apple-signin","lang":"bash","label":"yarn"},{"cmd":"pnpm add apple-signin","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Used to sign client secrets and verify ID tokens (JWT operations).","package":"jsonwebtoken","optional":false},{"reason":"May be used for JWT handling or key processing (depending on version).","package":"node-jose","optional":false}],"imports":[{"note":"Package is CommonJS-only; no ESM or default export. Use require().","wrong":"import appleSignin from 'apple-signin'","symbol":"appleSignin","correct":"const appleSignin = require('apple-signin')"},{"note":"Function name is exactly 'getAuthorizationUrl'. No destructuring alternative if you need multiple functions.","wrong":"const { getAuthUrl } = require('apple-signin')","symbol":"getAuthorizationUrl","correct":"const { getAuthorizationUrl } = require('apple-signin')"},{"note":"getClientSecret expects an object with specific keys; wrong casing or missing fields causes errors.","wrong":"const { getClientSecret } = require('apple-signin'); getClientSecret({...})","symbol":"getClientSecret","correct":"const appleSignin = require('apple-signin'); const secret = appleSignin.getClientSecret({clientID, teamId, privateKeyPath, keyIdentifier})"},{"note":"Second argument must be an options object containing clientID, redirectUri, and clientSecret.","wrong":"appleSignin.getAuthorizationToken(code, clientSecret) without options object","symbol":"getAuthorizationToken","correct":"const appleSignin = require('apple-signin'); appleSignin.getAuthorizationToken(code, options).then(...)"},{"note":"clientID is required as second argument to verify against expected audience.","wrong":"appleSignin.verifyIdToken(idToken) without clientID","symbol":"verifyIdToken","correct":"const appleSignin = require('apple-signin'); appleSignin.verifyIdToken(idToken, clientID).then(result => ...)"}],"quickstart":{"code":"const appleSignin = require('apple-signin');\n\n// Step 1: Generate authorization URL\nconst authUrl = appleSignin.getAuthorizationUrl({\n  clientID: process.env.APPLE_CLIENT_ID ?? '',\n  redirectUri: 'https://example.com/callback',\n  state: 'random-state-string',\n  scope: 'email'\n});\nconsole.log('Redirect user to:', authUrl);\n\n// Step 2: Exchange authorization code for tokens\nconst clientSecret = appleSignin.getClientSecret({\n  clientID: process.env.APPLE_CLIENT_ID ?? '',\n  teamId: process.env.APPLE_TEAM_ID ?? '',\n  privateKeyPath: '/path/to/AuthKey.p8',\n  keyIdentifier: process.env.APPLE_KEY_ID ?? ''\n});\n\nconst code = 'authorization-code-from-callback'; // obtain from query param\nappleSignin.getAuthorizationToken(code, {\n  clientID: process.env.APPLE_CLIENT_ID ?? '',\n  redirectUri: 'https://example.com/callback',\n  clientSecret\n}).then(tokenResponse => {\n  console.log('Token response:', tokenResponse);\n  // Step 3: Verify ID token\n  return appleSignin.verifyIdToken(tokenResponse.id_token, process.env.APPLE_CLIENT_ID ?? '');\n}).then(decoded => {\n  console.log('User unique identifier:', decoded.sub);\n}).catch(err => {\n  console.error('Authentication failed:', err);\n});\n","lang":"javascript","description":"Full authentication flow: generate auth URL, exchange code for tokens, verify ID token, and get user's unique Apple ID."},"warnings":[{"fix":"Consider using an actively maintained alternative like 'apple-auth' or implement OAuth manually using jsonwebtoken and axios.","message":"The library is unmaintained; last update in 2019. Apple's REST API may change, breaking compatibility.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Upgrade Node.js to active LTS (18 or 20) or higher.","message":"Node.js version < 12 may not support ES6 features used by dependencies. Minimum Node.js version unknown; test on Node 10+.","severity":"deprecated","affected_versions":">=1.0.0"},{"fix":"Provide file path string; if you have the key content, write to a temp file or modify the library.","message":"The 'privateKeyPath' parameter in getClientSecret must point to the key file; it does not accept the key content directly.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Ensure redirectUri matches exactly what is registered in Apple Developer Console.","message":"getAuthorizationToken expects an options object with clientID, redirectUri, clientSecret. Missing redirectUri will cause Apple to reject the request with a invalid_client error.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"After verification, check decoded.exp < Date.now()/1000 to ensure token is not expired.","message":"The id_token returned by Apple is a JWT signed with RSA256. The verifyIdToken function verifies signature but does not check token expiration ('exp') automatically; you should verify expiry separately.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"search_vec":"'1.0.9':26 '2019':65 'access':43 'account':18 'altern':84 'api':13,68 'appl':2,11,17,47,70,87,92,107 'apple-auth':86 'apple-signin':1 'applic':21 'around':6 'auth':88,109 'authent':15,112 'author':31,34 'browser':81 'cadenc':59 'callbacks/promises':105 'code':35 'configur':53 'current':22 'develop':48 'differenti':66 'enabl':14 'enrol':50 'exchang':33 'featur':96 'flow':73 'generat':30 'id':39,55 'integr':83 'javascript':106 'key':57 'last':62 'librari':98 'like':85 'limit':74 'login':110 'low':61 'may':93 'node':111 'node.js':4,20 'note':97 'oauth':72 'offer':94 'packag':28 'passport':91 'passport-appl':90 'privat':56 'program':49 'proper':52 'refresh':42 'releas':58 'requir':46 'rest':12 'sdk':82 'septemb':64 'server':77 'server-sid':76 'servic':54 'side':78 'sign':8 'signin':3,108 'simpl':67 'stabl':23 'support':29 'token':37,40,44 'type':103 'typescript':102 'unmaintain':100 'updat':63 'url':32 'use':79,104 'verifi':38 'version':24 'wrap':69 'wrapper':5","created_at":"2026-06-07T16:49:07.077180+00:00","updated_at":"2026-06-07T16:49:07.077180+00:00","problems":[{"fix":"Check that teamId, clientID, keyIdentifier, and privateKeyPath are correct. Regenerate private key if needed.","cause":"The client secret JWT is malformed or has mismatched claims (e.g., wrong teamId or clientID).","error":"Error: Invalid client secret"},{"fix":"Verify registered redirect URIs in Apple Developer; ensure case and path match exactly.","cause":"The redirectUri passed to getAuthorizationToken does not match exactly (including trailing slashes) with Apple Console configuration.","error":"Error: invalid_request: The 'redirect_uri' parameter does not match any registered redirect URI"},{"fix":"Ensure you are using the correct id_token (from latest token exchange) and that clientID matches the intended audience. Refresh token if expired.","cause":"The verification fails because token is expired, signed with wrong key, or audience does not match clientID.","error":"Error: The token is not valid or has expired"},{"fix":"Run 'npm install apple-signin' in your project directory.","cause":"Package not installed or not in node_modules.","error":"Error: Cannot find module 'apple-signin'"}],"ecosystem":"npm","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":null,"cli_version":null,"type":"library","homepage":"https://github.com/Techofficer/node-apple-signin#readme","github":"git://github.com/Techofficer/node-apple-signin","docs":null,"changelog":null,"pypi":null,"npm":"apple-signin","openapi_spec":null,"status_page":null,"smithery":null,"categories":["authentication"],"base_url":null,"auth_type":null,"provenance":{"verified_status":null,"verified_at":null,"last_verified":"2026-06-07","next_check":"2026-09-05","install_tag":null}}