Authentication
Overview
AuthrimClient exposes four authentication namespaces: passkey, emailCode, social, and session. All methods return AuthResponse<T> — a discriminated union of { data, error }.
For detailed protocol explanations (WebAuthn internals, PKCE flow, etc.), see the Web SDK documentation.
Passkey Authentication
Login
<script lang="ts"> import { getAuthContext } from '@authrim/sveltekit'; import { goto } from '$app/navigation';
const auth = getAuthContext();
let loading = $state(false); let error = $state('');
async function login() { loading = true; error = ''; const { data, error: err } = await auth.passkey.login();
if (err) { error = err.message; loading = false; return; }
goto('/'); }</script>
<button onclick={login} disabled={loading}> {loading ? 'Signing in...' : 'Sign in with Passkey'}</button>{#if error}<p class="error">{error}</p>{/if}Sign Up
const { data, error } = await auth.passkey.signUp({ displayName: 'Alice',});Register Additional Passkey
For authenticated users adding another passkey:
const { data, error } = await auth.passkey.register({ displayName: 'MacBook Pro',});// data.credentialId — the new credential IDConditional UI (Passkey Autofill)
<script lang="ts"> import { onMount, onDestroy } from 'svelte'; import { getAuthContext } from '@authrim/sveltekit'; import { goto } from '$app/navigation';
const auth = getAuthContext();
onMount(async () => { if (await auth.passkey.isConditionalUIAvailable()) { const { data } = await auth.passkey.login({ conditional: true }); if (data) goto('/'); } });
onDestroy(() => auth.passkey.cancelConditionalUI());</script>
<input type="text" autocomplete="username webauthn" placeholder="Email" />Passkey API Reference
| Method | Signature | Description |
|---|---|---|
login(options?) | (PasskeyLoginOptions?) → AuthResponse<AuthSessionData> | Login with passkey |
signUp(options) | (PasskeySignUpOptions) → AuthResponse<AuthSessionData> | Register + login |
register(options?) | (PasskeyRegisterOptions?) → AuthResponse<PasskeyCredential> | Add passkey to existing account |
isSupported() | () → boolean | Check WebAuthn support |
isConditionalUIAvailable() | () → Promise<boolean> | Check conditional UI support |
cancelConditionalUI() | () → void | Cancel pending conditional request |
Email Code Authentication
Two-step flow: send a code to an email address, then verify it.
Send Code
if (data) { console.log('Code sent, expires in:', data.expiresIn, 'seconds');}Verify Code
const { data, error } = await auth.emailCode.verify( '123456',);
if (data) { // Authenticated — data.session, data.user available}Full Email Code Flow
<script lang="ts"> import { getAuthContext } from '@authrim/sveltekit'; import { goto } from '$app/navigation';
const auth = getAuthContext();
let step: 'email' | 'code' = $state('email'); let email = $state(''); let code = $state(''); let loading = $state(false); let error = $state('');
async function sendCode() { loading = true; error = ''; const { error: err } = await auth.emailCode.send(email); loading = false;
if (err) { error = err.message; return; } step = 'code'; }
async function verifyCode() { loading = true; error = ''; const { data, error: err } = await auth.emailCode.verify(email, code); loading = false;
if (err) { error = err.message; return; } goto('/'); }</script>
{#if step === 'email'} <form onsubmit={sendCode}> <input type="email" bind:value={email} placeholder="Email" required /> <button type="submit" disabled={loading}>Send Code</button> </form>{:else} <p>Code sent to {email}</p> <form onsubmit={verifyCode}> <input type="text" bind:value={code} placeholder="Enter 6-digit code" inputmode="numeric" maxlength="6" required /> <button type="submit" disabled={loading}>Verify</button> </form> <button onclick={() => step = 'email'}>Back</button>{/if}
{#if error}<p class="error">{error}</p>{/if}Email Code API Reference
| Method | Signature | Description |
|---|---|---|
send(email, options?) | (string, EmailCodeSendOptions?) → AuthResponse<EmailCodeSendResult> | Send verification code |
verify(email, code, options?) | (string, string, EmailCodeVerifyOptions?) → AuthResponse<AuthSessionData> | Verify code and authenticate |
hasPendingVerification(email) | (string) → boolean | Check if code was sent |
getRemainingTime(email) | (string) → number | Seconds until code expires |
clearPendingVerification(email) | (string) → void | Clear pending state |
Social Login
Popup Login
const { data, error } = await auth.social.loginWithPopup('google');Redirect Login
// Step 1: Redirect (navigates away)await auth.social.loginWithRedirect('github');
// Step 2: Handle callback (in /callback page)if (auth.social.hasCallbackParams()) { const { data, error } = await auth.social.handleCallback(); if (data) window.location.href = '/';}Callback Page
<script lang="ts"> import { onMount } from 'svelte'; import { goto } from '$app/navigation'; import { getAuthContext } from '@authrim/sveltekit';
const auth = getAuthContext();
let error = $state(''); let processing = $state(true);
onMount(async () => { if (!auth.social.hasCallbackParams()) { goto('/'); return; }
const { data, error: err } = await auth.social.handleCallback(); processing = false;
if (err) { error = err.message; return; }
goto(data.redirectTo ?? '/'); });</script>
{#if processing} <p>Processing login...</p>{:else if error} <p class="error">{error}</p> <a href="/login">Try again</a>{/if}Social API Reference
| Method | Signature | Description |
|---|---|---|
loginWithPopup(provider, options?) | (SocialProvider, SocialLoginOptions?) → AuthResponse<AuthSessionData> | Popup login |
loginWithRedirect(provider, options?) | (SocialProvider, SocialLoginOptions?) → Promise<void> | Redirect login |
handleCallback() | () → AuthResponse<AuthSessionData> | Process callback |
hasCallbackParams() | () → boolean | Check for callback params |
getSupportedProviders() | () → SocialProvider[] | List configured providers |
Session Management
// Get current sessionconst { data } = await auth.session.get();
// Validate sessionconst isValid = await auth.session.validate();
// Refresh sessionconst newSession = await auth.session.refresh();
// Check authenticationconst authed = await auth.session.isAuthenticated();
// Get current userconst user = await auth.session.getUser();
// Clear client-side session cacheauth.session.clearCache();Sign Out
await auth.signOut();
// With redirectawait auth.signOut({ redirectUri: '/goodbye' });
// With token revocationawait auth.signOut({ revokeTokens: true });Shortcut Methods
For common operations:
// Same as auth.passkey.login()const { data, error } = await auth.signIn.passkey();
// Same as auth.social.loginWithPopup(provider)const { data, error } = await auth.signIn.social('google');
// Same as auth.passkey.signUp(options)const { data, error } = await auth.signUp.passkey({ displayName: 'Alice' });AuthResponse Pattern
All authentication methods return AuthResponse<T>:
type AuthResponse<T> = | { data: T; error: null } | { data: null; error: AuthError };
interface AuthError { code: string; error: string; message: string; retryable: boolean; severity: 'info' | 'warn' | 'error' | 'critical';}Always check error first:
const { data, error } = await auth.passkey.login();if (error) { // Handle error return;}// Use data safelyFor error code details, see Web SDK Error Handling.
Next Steps
- Stores & Events — Reactive state and events
- Components — Pre-built auth components
- UI Library — Full component catalog