SvelteKit + Passkeys + Lucia
In this tutorial you'll build on your previous work to integrate passkeys with Lucia users and sessions. You'll handle session creation, expiry and invalidation, and protect your routes using SvelteKit hooks.
We're now live! Signup now
If you've followed the previous instalments in this series, you'll have built a SvelteKit app with passkey authentication, session management and authorization. It's functional, but it feels a bit clunky. Let's improve things.
This tutorial forms the third part of our SvelteKit series. If you haven’t already done so, please read the first and second tutorials. In this instalment, we’ll add a loading spinner to give the user feedback that things are happening.
Perceived performance is just as important as actual performance. If we’re waiting for a browser API or network call to complete, we want to give the user feedback that things are happening. We’ll go for a simple spinner. Update src/routes/register/+page.svelte
:
<!-- src/routes/register/+page.svelte --> <script lang="ts"> import Spinner from '$lib/Spinner.svelte' import { enhance } from '$app/forms' import { register } from '@passlock/sveltekit' import { PUBLIC_PASSLOCK_TENANCY_ID, PUBLIC_PASSLOCK_CLIENT_ID } from '$env/static/public' // submitting is a Svelte boolean store const { onSubmit, submitting } = register({ tenancyId: PUBLIC_PASSLOCK_TENANCY_ID, clientId: PUBLIC_PASSLOCK_CLIENT_ID }) </script> <form method="post" use:enhance={onSubmit}> Email: <input type="text" name="email" /> <br /> First name: <input type="text" name="givenName" /> <br /> Last name: <input type="text" name="familyName" /> <br /> <button type="submit">Register</button> {#if $submitting} <Spinner /> {/if} </form>
src/lib/Spinner.svelte
:
<!-- src/lib/Spinner.svelte --> <svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <path d="M10.14,1.16a11,11,0,0,0-9,8.92A1.59,1.59,0,0,0,2.46,12,1.52,1.52,0,0,0,4.11,10.7a8,8,0,0,1,6.66-6.61A1.42,1.42,0,0,0,12,2.69h0A1.57,1.57,0,0,0,10.14,1.16Z"> <animateTransform attributeName="transform" type="rotate" dur="0.75s" values="0 12 12;360 12 12" repeatCount="indefinite" /> </path> </svg>
Spinner.svelte
is just an SVG spinner wrapped as a Svelte component. You're free to use anything here, even a simple "loading..." message.The Passlock extension returns a boolean store. We can use this to toggle a spinner.
Now do the same for the src/routes/login
route:
<!-- src/routes/login/+page.svelte --> <script lang="ts"> import Spinner from '$lib/Spinner.svelte' import { enhance } from '$app/forms' import { login } from '@passlock/sveltekit' import { PUBLIC_PASSLOCK_TENANCY_ID, PUBLIC_PASSLOCK_CLIENT_ID } from '$env/static/public' const { onSubmit, submitting } = login({ tenancyId: PUBLIC_PASSLOCK_TENANCY_ID, clientId: PUBLIC_PASSLOCK_CLIENT_ID }) </script> <form method="post" use:enhance={onSubmit}> Email: <input type="text" name="email" /> <br /> <button type="submit">Login</button> {#if $submitting} <Spinner /> {/if} </form>
Passkeys are a great alternative to passwords, but many users still prefer to sign in using a social network account. Fortunately the Passlock library also supports Social Sign In. That’s the next tutorial in this series…
Founder
In this tutorial you'll build on your previous work to integrate passkeys with Lucia users and sessions. You'll handle session creation, expiry and invalidation, and protect your routes using SvelteKit hooks.
In this tutorial you'll learn how to add passkey authentication to your SvelteKit apps. You'll register a passkey and use it to login. In subsequent tutorials I'll show you how to add session management, social login and more.
All the major browsers now support passkeys, however biometric support is often limited to those browsers with tight platform integration e.g. Safari on iOS and Chrome on Android.
Passkeys are tied to specific (https) websites. Browsers won't use a private key intended for one website to sign a challenge generated by a different site.
Roaming authenticators allow users to sign in to a website on one device, using a passkey stored on a different device.
Passkeys enable two factor authentication (including biometrics). Users can even use a biometric enabled device e.g. iPhone FaceID to authenticate against a device lacking this capability e.g. a desktop.