Skip to content

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',
username: '[email protected]', // optional
});

Register Additional Passkey

For authenticated users adding another passkey:

const { data, error } = await auth.passkey.register({
displayName: 'MacBook Pro',
});
// data.credentialId — the new credential ID

Conditional 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

MethodSignatureDescription
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()() → booleanCheck WebAuthn support
isConditionalUIAvailable()() → Promise<boolean>Check conditional UI support
cancelConditionalUI()() → voidCancel pending conditional request

Email Code Authentication

Two-step flow: send a code to an email address, then verify it.

Send Code

const { data, error } = await auth.emailCode.send('[email protected]');
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

MethodSignatureDescription
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) → booleanCheck if code was sent
getRemainingTime(email)(string) → numberSeconds until code expires
clearPendingVerification(email)(string) → voidClear pending state

Social 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

src/routes/callback/+page.svelte
<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

MethodSignatureDescription
loginWithPopup(provider, options?)(SocialProvider, SocialLoginOptions?) → AuthResponse<AuthSessionData>Popup login
loginWithRedirect(provider, options?)(SocialProvider, SocialLoginOptions?) → Promise<void>Redirect login
handleCallback()() → AuthResponse<AuthSessionData>Process callback
hasCallbackParams()() → booleanCheck for callback params
getSupportedProviders()() → SocialProvider[]List configured providers

Session Management

// Get current session
const { data } = await auth.session.get();
// Validate session
const isValid = await auth.session.validate();
// Refresh session
const newSession = await auth.session.refresh();
// Check authentication
const authed = await auth.session.isAuthenticated();
// Get current user
const user = await auth.session.getUser();
// Clear client-side session cache
auth.session.clearCache();

Sign Out

await auth.signOut();
// With redirect
await auth.signOut({ redirectUri: '/goodbye' });
// With token revocation
await 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 safely

For error code details, see Web SDK Error Handling.

Next Steps