IntegrateSPA & mobile
SvelteKit integration
Authenticate a SvelteKit app against Olympus
SvelteKit's server-side hooks make Olympus integration clean.
Setup
bun add oauth4webapiHook for session check
src/hooks.server.ts:
import type { Handle } from "@sveltejs/kit";
export const handle: Handle = async ({ event, resolve }) => {
const session = event.cookies.get("session");
if (session) {
try {
event.locals.user = JSON.parse(session);
} catch {}
}
return resolve(event);
};Login server endpoint
src/routes/api/auth/login/+server.ts:
import { redirect } from "@sveltejs/kit";
import * as oauth from "oauth4webapi";
export const GET = async ({ cookies }) => {
const issuer = new URL(process.env.OLYMPUS_ISSUER!);
const as = await oauth.processDiscoveryResponse(issuer, await oauth.discoveryRequest(issuer));
const verifier = oauth.generateRandomCodeVerifier();
const challenge = await oauth.calculatePKCECodeChallenge(verifier);
const state = oauth.generateRandomState();
cookies.set("pkce_verifier", verifier, { path: "/", httpOnly: true, secure: true, sameSite: "lax" });
cookies.set("pkce_state", state, { path: "/", httpOnly: true, secure: true, sameSite: "lax" });
const url = new URL(as.authorization_endpoint!);
url.search = new URLSearchParams({
client_id: process.env.OLYMPUS_CLIENT_ID!,
response_type: "code",
scope: "openid profile email",
redirect_uri: process.env.OLYMPUS_REDIRECT_URI!,
code_challenge: challenge,
code_challenge_method: "S256",
state,
}).toString();
throw redirect(302, url.toString());
};Page with auth check
src/routes/+page.svelte:
<script lang="ts">
export let data;
</script>
{#if data.user}
<p>Welcome, {data.user.email}</p>
{:else}
<a href="/api/auth/login">Log in</a>
{/if}src/routes/+page.server.ts:
export const load = async ({ locals }) => {
return { user: locals.user };
};