Apple
Documentationβ
https://developer.apple.com/sign-in-with-apple/get-started/
Configurationβ
https://developer.apple.com/account/resources/identifiers/list/serviceId
Optionsβ
The Apple Provider comes with a set of default options:
You can override any of the options to suit your own use case.
Exampleβ
There are two ways you can use the Sign in with Apple provider.
Dynamically generated secretβ
If you use a dynamically generated secret you never have to manually update the server.
import Providers from `next-auth/providers`
...
providers: [
Providers.Apple({
clientId: process.env.APPLE_ID,
clientSecret: {
teamId: process.env.APPLE_TEAM_ID,
privateKey: process.env.APPLE_PRIVATE_KEY,
keyId: process.env.APPLE_KEY_ID,
}
})
]
...
You can convert your Apple key to a single line to use it in an environment variable.
Mac
awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' AuthKey_ID.k8
Windows
$k8file = "AuthKey_ID.k8"
(Get-Content "C:\Users\$env:UserName\Downloads\${k8file}") -join "\n"
Pre-generated secretβ
If you use a pre-generated secret you can avoid adding your private key as an environment variable.
import Providers from `next-auth/providers`
...
providers: [
Providers.Apple({
clientId: process.env.APPLE_ID,
clientSecret: process.env.APPLE_KEY_SECRET
})
]
...
The TeamID is located on the top right after logging in.
The KeyID is located after you create the Key look for before you download the k8 file.
Instructionsβ
Testingβ
Apple requires all sites to run HTTPS (including local development instances).
Apple doesn't allow you to use localhost in domains or subdomains.
The following guides may be helpful:
Example serverβ
You will need to edit your host file and point your site at 127.0.0.1
On Windows (Run Powershell as administrator)
Add-Content -Path C:\Windows\System32\drivers\etc\hosts -Value "127.0.0.1`tdev.example.com" -Force
127.0.0.1 dev.example.com
Create certificateβ
Creating a certificate for localhost is easy with openssl . Just put the following command in the terminal. The output will be two files: localhost.key and localhost.crt.
openssl req -x509 -out localhost.crt -keyout localhost.key \
-newkey rsa:2048 -nodes -sha256 \
-subj '/CN=localhost' -extensions EXT -config <( \
printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")
Windows
The OpenSSL executable is distributed with Git for Windows.
Once installed you will find the openssl.exe file in C:/Program Files/Git/mingw64/bin
which you can add to the system PATH environment variable if itβs not already done.
Add environment variable OPENSSL_CONF=C:/Program Files/Git/mingw64/ssl/openssl.cnf
req -x509 -out localhost.crt -keyout localhost.key \
-newkey rsa:2048 -nodes -sha256 \
-subj '/CN=localhost'
Create directory certificates
and place localhost.key
and localhost.crt
You can create a server.js
in the root of your project and run it with node server.js
to test Sign in with Apple integration locally:
const { createServer } = require("https")
const { parse } = require("url")
const next = require("next")
const fs = require("fs")
const dev = process.env.NODE_ENV !== "production"
const app = next({ dev })
const handle = app.getRequestHandler()
const httpsOptions = {
key: fs.readFileSync("./certificates/localhost.key"),
cert: fs.readFileSync("./certificates/localhost.crt"),
}
app.prepare().then(() => {
createServer(httpsOptions, (req, res) => {
const parsedUrl = parse(req.url, true)
handle(req, res, parsedUrl)
}).listen(3000, (err) => {
if (err) throw err
console.log("> Ready on https://localhost:3000")
})
})
Example JWT codeβ
If you want to pre-generate your secret, this is an example of the code you will need:
const jwt = require("jsonwebtoken")
const fs = require("fs")
const appleId = "myapp.example.com"
const keyId = ""
const teamId = ""
const privateKey = fs.readFileSync("path/to/key")
const secret = jwt.sign(
{
iss: teamId,
iat: Math.floor(Date.now() / 1000),
exp: Math.floor(Date.now() / 1000) + 86400 * 180, // 6 months
aud: "https://appleid.apple.com",
sub: appleId,
},
privateKey,
{
algorithm: "ES256",
keyid: keyId,
}
)
console.log(secret)