implement a basic JWT auth

This commit is contained in:
Shahrad Elahi 2023-11-03 18:45:08 +03:30
parent d06bf3f460
commit eabab0e2f1
7 changed files with 55 additions and 2 deletions

Binary file not shown.

View File

@ -10,11 +10,13 @@
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"test": "vitest",
"lint": "prettier --plugin-search-dir . --check .",
"format": "prettier --plugin-search-dir . --write ."
"format": "prettier --plugin-search-dir . --write .",
"start": "bun ./build/index.js"
},
"devDependencies": {
"@sveltejs/adapter-auto": "^2.0.0",
"@sveltejs/kit": "^1.20.4",
"@types/jsonwebtoken": "^9.0.4",
"autoprefixer": "^10.4.14",
"postcss": "^8.4.24",
"postcss-load-config": "^4.0.1",
@ -32,6 +34,7 @@
"dependencies": {
"bits-ui": "^0.9.0",
"clsx": "^2.0.0",
"jsonwebtoken": "^9.0.2",
"lucide-svelte": "^0.292.0",
"tailwind-merge": "^2.0.0",
"tailwind-variants": "^0.1.18"

34
web/src/hooks.server.ts Normal file
View File

@ -0,0 +1,34 @@
import type { Handle } from '@sveltejs/kit';
import { verifyToken } from '$lib/auth';
export const handle: Handle = async ({ event, resolve }) => {
if (event.url.pathname.startsWith('/custom')) {
const resp = new Response('custom response');
resp.headers.set('content-type', 'text/plain');
return resp;
}
const auth_exception = ['/api/health', '/login'];
if (!auth_exception.includes(event.url.pathname)) {
const token = event.cookies.get('authorization');
const redirect = new Response(null, { status: 302, headers: { location: '/login' } });
if (!token) {
console.log('handle', event.url.pathname, 'no token');
return redirect;
}
const token_valid = await verifyToken(token);
if (!token_valid) {
console.log('handle', event.url.pathname, 'invalid token');
return redirect;
}
}
const resp = await resolve(event);
console.log('handle', event.url.pathname, resp.status);
return resp;
};

15
web/src/lib/auth.ts Normal file
View File

@ -0,0 +1,15 @@
import jwt from 'jsonwebtoken';
import { AUTH_SECRET } from '$env/static/private';
export async function generateToken(): Promise<string> {
return jwt.sign('OK', AUTH_SECRET, { expiresIn: '1d' });
}
export async function verifyToken(token: string): Promise<boolean> {
try {
const decode = jwt.verify(token, AUTH_SECRET);
return !!(decode && decode === 'OK');
} catch (e) {
return false;
}
}

View File

@ -1,5 +1,5 @@
<script lang="ts">
import '../app.postcss';
import '../app.css';
import '$lib/assets/fontawesome/index.css';
</script>

View File

@ -0,0 +1 @@
<h1>Hello World!</h1>