OAuth and Third-Party Authentication Headers
OAuth and Third-Party Authentication Headers
OAuth2 Security Headers Implementation
// OAuth2 authorization endpoint
app.get('/oauth/authorize', (req, res) => {
// Set security headers for OAuth flow
res.setHeader('X-Frame-Options', 'DENY'); // Prevent clickjacking
res.setHeader('Content-Security-Policy', "frame-ancestors 'none'");
res.setHeader('Cache-Control', 'no-store');
res.setHeader('Pragma', 'no-cache');
// PKCE (Proof Key for Code Exchange) for public clients
const codeChallenge = req.query.code_challenge;
const codeChallengeMethod = req.query.code_challenge_method;
if (req.query.response_type === 'code' && !codeChallenge) {
return res.status(400).json({
error: 'invalid_request',
error_description: 'PKCE required for public clients'
});
}
// Generate authorization code
const authCode = generateAuthorizationCode({
clientId: req.query.client_id,
userId: req.session.userId,
redirectUri: req.query.redirect_uri,
scope: req.query.scope,
codeChallenge: codeChallenge,
codeChallengeMethod: codeChallengeMethod
});
// Set state cookie for CSRF protection
if (req.query.state) {
res.cookie('oauth_state', req.query.state, {
secure: true,
httpOnly: true,
sameSite: 'lax', // Allow for OAuth redirects
maxAge: 600000 // 10 minutes
});
}
// Redirect with authorization code
const redirectUrl = new URL(req.query.redirect_uri);
redirectUrl.searchParams.set('code', authCode);
redirectUrl.searchParams.set('state', req.query.state);
res.redirect(redirectUrl.toString());
});
// Token endpoint with security headers
app.post('/oauth/token', (req, res) => {
// Security headers for token endpoint
res.setHeader('Cache-Control', 'no-store');
res.setHeader('Pragma', 'no-cache');
res.setHeader('Content-Type', 'application/json;charset=UTF-8');
res.setHeader('X-Content-Type-Options', 'nosniff');
res.setHeader('X-Frame-Options', 'DENY');
// CORS headers for public clients
const origin = req.headers.origin;
const allowedOrigins = ['https://app.example.com', 'https://mobile.example.com'];
if (allowedOrigins.includes(origin)) {
res.setHeader('Access-Control-Allow-Origin', origin);
res.setHeader('Access-Control-Allow-Methods', 'POST');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
}
// Token generation logic...
});