Implement Apple authentication routes
masterApple's authentication flow involves a POST request to your callback URL. Because browser SameSite policies often prevent cookies (and thus sessions) from being sent with external POST requests, you should redirect the POST request to a GET request using query parameters before passing it to Passport.
// 1. Initial login request
app.get('/apple', passport.authenticate('apple'));
// 2. Handle the POST from Apple: Redirect POST to GET to preserve session/cookies
app.post('/apple/callback', express.urlencoded({ extended: true }), (req, res) => {
const { body } = req;
const sp = new URLSearchParams();
Object.entries(body).forEach(([key, value]) => sp.set(key, String(value)));
res.redirect(`/v1/auth/apple/callback?${sp.toString()}`);
});
// 3. Handle the GET request (the actual Passport authentication)
const failureRedirect = '/failure';
app.get('/apple/callback', passport.authenticate('apple', {
successReturnToOrRedirect: '/success',
failureRedirect,
}), (err, _req, res, _next) => {
// Handle specific Apple errors
if (err instanceof Error && (err.name === 'AuthorizationError' || err.name === 'TokenError')) {
const sp = new URLSearchParams({ error: err.name });
if ('code' in err && typeof err.code === 'string') sp.set('code', err.code);
res.redirect(`${failureRedirect}${sp.toString()}`);
return;
}
res.redirect(failureRedirect);
});