cloudflare-apple-sign-in
A library for implementing Sign In With Apple Rest API in Cloudflare Workers. Forked from renarsvilnis/apple-sign-in-rest
See comparison table why you should choose apple-sign-in-rest
over other apple-xxx
package.
Supports Cloudflare Workers runtime.
Installation
Install the package:
npm install cloudflare-apple-sign-in
Documentation
Library is built on typescript and has well documented source code. This will provide a zero-effort developer expierence within your existing code editors. But the library also provides autogenered documentation using typedoc.
Documentation
Usage
0. Prerequisites
Here are some usefull links to get started with Sign In with Apple:
1. Create a AppleSignIn
instance
Compared to other libraries apple-sign-in-rest
chooses to create an instance with credentials instead of passing same credentials to functions on each call. This allows the library to validate them once and create apple public key cache per instance.
import {AppleSignIn} from 'apple-sign-in-rest';
const {AppleSignIn} = require("apple-sign-in-rest");
const appleSignIn = new AppleSignIn({
clientId: "com.my-company.my-app",
teamId: "5B645323E8",
keyIdentifier: "U3B842SVGC",
privateKey: "-----BEGIN PRIVATE KEY-----\nMIGTAgEHIHMJKJyqGSM32AgEGC..."
})
2. (Optional) Get authorization URL
Start "Sign in with Apple" flow by redirecting user to the authorization URL.
Alternatively, you can use Sign In with Apple browser javascript library to handle this.
If you implement in Sign In With Apple trough iOS native login, you won't need to do this.
const authorizationUrl = appleSignIn.getAuthorizationUrl({
scope: ["name", "email"],
redirectUri: "http://localhost:3000/auth/apple/callback",
state: "123",
nonce: "insert-generated-uuid",
});
2. Get access token
2.1. Get credentials return after successful sign in with Apple
Retrieve the "code" query parameter from the URL string when the user user redirect to your sites previously provided redirectUrl
after a successfull Sign In With Apple.
Make sure to verify that the state
matches what was set when creating the authorization url!
app.get("/auth/apple/callback", (req, res) => {
const code = req.query.code;
const state = req.query.state;
if (req.session.state && req.session.state !== state) {
throw new Error("Missing or invalid state");
}
});
In the case of iOS the native-app sends the code
to a custom endpoint on your app. Make sure that iOS app also securily passes along the fullName
and idToken
. From the backend you won't have access to the fullName
and idToken
can be used to verify the user without making appleSignIn.getAuthorization()
call.
2.2. Create a userSecret
const clientSecret = appleSignIn.createClientSecret({
expirationDuration: 5 * 60,
});
2.2. Exchange retrieved "code" to user's access token.
const tokenResponse = await appleSignIn.getAuthorizationToken(clientSecret, code, {
redirectUri: "http://localhost:3000/auth/apple/callback",
});
Result of appleSignIn.getAuthorizationToken
command is a JSON object representing Apple's TokenResponse:
{
access_token: "ACCESS_TOKEN",
token_type: 'Bearer',
expires_in: 3600,
refresh_token: "REFRESH_TOKEN",
id_token: "ID_TOKEN"
}
2.4. Verify token signature and get unique user's identifier
const claim = await appleSignIn.verifyIdToken(tokenResponse.id_token, {
nonce: "nonce",
subject: "000852.5g3d8d4b3db045b48b7a58fb07728e1e.1303",
ignoreExpiration: true,
});
3. Refresh access token after expiration
Should call it no more once a day, else apple amy throttle your request.
const refreshTokenResponse = await appleSignIn.refreshAuthorizationToken(clientSecret, refreshToken);
const { access_token } = refreshTokenResponse.access_token;
Comparison to other "apple sign in" libraries
There are many already packages on npm with very similar names. Most of them are missing features and/or abandoned. This package takes inspiration from apple-signin
and implements features/fixes while comparing to other libraries.
The only other library I'd consider feature-full and ready to use besides this one is apple-signin-auth by A-Tokyo, seem to have missing key features.
| apple-sign-in-rest | apple-signin-auth | apple-auth | apple-signin |
---|
Feature Full | ✅ | ✅ (missing some minor options) | ❌ | ❌ |
Apple Public Key Caching | ✅ (cache per class instance) | ✅ (global cache) | ❌ | ❌ |
Passport.js library | ❌ (comming-soon) | ❌ | ✅ | ✅ |
Typed Support | ✅ (typescript based) | ✅ (flow based) | ❌ | ❌ |
API Documentation | ✅ (auto generated docs using typedoc) | ❌ | ❌ | ❌ |
Usage Examples | ✅ | ✅ | ✅ | ✅ |
Tools for easier contributors | ✅ (typescript, eslint, prettier, jest) | ✅ (flow, eslint, prettier, jest) | ❌ | ❌ |
Stats |  |  |  |  |
Contributing
Pull requests are always welcomed. 🙇🏻♂️ Please open an issue first to discuss what you would like to change.
Package has a pre-commit git hook that does typechecking, linting, unit testing and doc building (if see source code changes).
Helper scripts
npm run build
npm run test
npm run test:watch
npm run lint
npm run format
npm run docs
npm run docs:serve
DOCS_FORCE=true git commit -m 'My awesome change'
DOCS_COMMIT=false git commit -m 'My awesome change'
git commit -m 'My awesome change' --no-verify
License
The MIT License
Copyright (c) 2020 Renārs Vilnis
Support
If you have any questions or need help with integration, then you can contact me by email
renars.vilnis@gmail.com.