Created
December 29, 2023 12:18
-
-
Save Accudio/a85424cd143cfbf159fa846087c0702a to your computer and use it in GitHub Desktop.
Basic authentication using Vercel edge functions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import bcrypt from 'bcrypt'; | |
import { SignJWT } from 'jose'; | |
import { serialize } from 'cookie'; | |
export default async function (request, response) { | |
if (request.method !== "POST") { | |
return response.status(405).send('does not respond to GET requests'); | |
} | |
// get all configured passwords | |
const configItems = await getEdgeConfig() | |
const users = Object.entries(configItems.users) | |
.map(([name, { password }]) => ({ | |
name, | |
password | |
})); | |
// check entered password against all configured and if valid return true | |
for (const user of users) { | |
const match = bcrypt.compareSync(request.body.password, user.password); | |
if (match) { | |
const jwt = await new SignJWT({ | |
sub: user.name | |
}) | |
.setProtectedHeader({ alg: 'HS256' }) | |
.setIssuedAt() | |
.setIssuer('https://xxxxxxxxx.vercel.app') | |
.setExpirationTime('90d') | |
.sign(new TextEncoder().encode(process.env.JWT_SIGNING_KEY)); | |
const cookie = serialize( | |
'session', | |
jwt, | |
{ | |
httpOnly: true, | |
maxAge: 7776000, | |
sameSite: 'lax', | |
path: '/' | |
} | |
) | |
response.setHeader('Set-Cookie', [cookie]); | |
return response.redirect(303, '/'); | |
} | |
} | |
return response.redirect(303, '/auth') | |
} | |
async function getEdgeConfig() { | |
const res = await fetch(process.env.EDGE_CONFIG) | |
const json = await res.json(); | |
return json.items | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8" /> | |
<meta name="viewport" content="width=device-width,initial-scale=1"> | |
<title>Login</title> | |
</head> | |
<body> | |
<main> | |
<form action="/api/auth/" method="post"> | |
<label for="password"> | |
<div>Please enter password</div> | |
<input | |
name="password" | |
id="password" | |
type="password" | |
autocomplete="false" | |
required | |
/> | |
</label> | |
<button type="submit">Login</button> | |
</form> | |
</main> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { RequestCookies } from '@edge-runtime/cookies'; | |
import { jwtVerify } from 'jose'; | |
export const config = { | |
matcher: '/', | |
}; | |
export default async function middleware(request) { | |
try { | |
const cookies = new RequestCookies(request.headers) | |
const sessionCookie = cookies.get('session'); | |
if (!sessionCookie) return auth(request) | |
await jwtVerify( | |
sessionCookie.value, | |
new TextEncoder().encode(process.env.JWT_SIGNING_KEY) | |
); | |
} catch (e) { | |
console.error(e) | |
return auth(request) | |
} | |
} | |
function auth(request) { | |
return Response.redirect(new URL('/auth', request.url), 303); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const bcrypt = require('bcrypt') | |
password() | |
function password() { | |
const password = process.argv[2] | |
if (!password) return console.error('no password provided') | |
const salt = bcrypt.genSaltSync(10) | |
const hash = bcrypt.hashSync(password, salt) | |
return console.log('Password hash:', hash) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment