feat: add GitHub OAuth2 login and protect product mutations with JWT
- add /auth/login and /auth/callback (rewritten to pages/api/auth/*) for the GitHub Authorization Code flow, with a state cookie against login CSRF - issue a 1h JWT after the code exchange and verify it (HS256) in the Apollo context; createProduct, updateProduct and deleteProduct require it - set products.created_by from the logged-in GitHub user (upsert into users) - preset the Authorization header in the embedded Sandbox - add jsonwebtoken, drop unused cors, rename package to week-7
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
const crypto = require('crypto');
|
||||
|
||||
// Langkah 1 OAuth2: arahkan pengguna ke halaman login GitHub.
|
||||
module.exports = function handler(req, res) {
|
||||
const { GITHUB_CLIENT_ID, CALLBACK_URL } = process.env;
|
||||
if (!GITHUB_CLIENT_ID || !CALLBACK_URL) {
|
||||
res.status(500).json({ error: 'GITHUB_CLIENT_ID / CALLBACK_URL belum diatur di environment' });
|
||||
return;
|
||||
}
|
||||
|
||||
// Cookie state hanya terkirim ke host yang sama dengan CALLBACK_URL, jadi login harus dimulai di host itu.
|
||||
const callbackUrl = new URL(CALLBACK_URL);
|
||||
if (req.headers.host !== callbackUrl.host) {
|
||||
res.redirect(`${callbackUrl.origin}/auth/login`);
|
||||
return;
|
||||
}
|
||||
|
||||
// state acak disimpan di cookie lalu dicocokkan di /auth/callback (anti login-CSRF).
|
||||
const state = crypto.randomBytes(16).toString('hex');
|
||||
const secure = process.env.NODE_ENV === 'production' ? '; Secure' : '';
|
||||
res.setHeader(
|
||||
'Set-Cookie',
|
||||
`oauth_state=${state}; HttpOnly; SameSite=Lax; Path=/; Max-Age=600${secure}`
|
||||
);
|
||||
|
||||
const params = new URLSearchParams({
|
||||
client_id: GITHUB_CLIENT_ID,
|
||||
redirect_uri: CALLBACK_URL,
|
||||
state,
|
||||
});
|
||||
res.redirect(`https://github.com/login/oauth/authorize?${params}`);
|
||||
};
|
||||
Reference in New Issue
Block a user