Skip to content

Commit

Permalink
chore(sveltekit): update more current docs to latest SvelteKitAuth AP…
Browse files Browse the repository at this point in the history
…I and finish example app migration to latest API (#10191)
  • Loading branch information
ndom91 authored Mar 2, 2024
1 parent b7dc100 commit 8cc2a0f
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 35 deletions.
5 changes: 2 additions & 3 deletions apps/dev/sveltekit/src/routes/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<script lang="ts">
import { page } from "$app/stores"
import { SignIn, SignOut } from "@auth/sveltekit/components"
import { signIn, signOut } from "@auth/sveltekit/client"
import { SignIn } from "@auth/sveltekit/components"
import { signIn } from "@auth/sveltekit/client"
let password = ""
</script>
Expand Down
2 changes: 1 addition & 1 deletion apps/examples/sveltekit/src/components/header.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
{$page.data.session.user?.email ?? $page.data.session.user?.name}
</span>
<SignOut>
<div class="buttonPrimary">Sign out</div>
<div slot="submitButton" class="buttonPrimary">Sign out</div>
</SignOut>
{:else}
<span class="notSignedInText">You are not signed in</span>
Expand Down
117 changes: 86 additions & 31 deletions packages/frameworks-sveltekit/src/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,14 @@
* [origin]/auth/callback/[provider]
* ```
*
* ## Signing in and signing out
* ## Signing in and Signing out
*
* The data for the current session in this example was made available through the `$page` store which can be set through the root `+page.server.ts` file.
* It is not necessary to store the data there, however, this makes it globally accessible throughout your application simplifying state management.
* ### Server-side
*
* `<SignIn />` and `<SignOut />` are components that `@auth/sveltekit` provides out of the box - they handle the sign-in/signout flow, and can be used as-is as a starting point or customized for your own components. This is an example of how to use the `SignIn` and `SignOut` components to login and logout using SvelteKit's server-side form actions. You will need two things to make this work:
*
* 1. Using the components in your SvelteKit app's frontend
* 2. Add the required `page.server.ts` at `/signin` (for `SignIn`) and `/signout` (for `SignOut`) to handle the form actions
*
* ```ts
* <script>
Expand All @@ -71,38 +75,86 @@
* <div>
* {#if $page.data.session}
* {#if $page.data.session.user?.image}
* <span
* style="background-image: url('{$page.data.session.user.image}')"
* <img
* src={$page.data.session.user.image}
* class="avatar"
* alt="User Avatar"
* />
* {/if}
* <span class="signedInText">
* <small>Signed in as</small><br />
* <strong>{$page.data.session.user?.name ?? "User"}</strong>
* </span>
* <SignOut />
* <SignOut>
* <div slot="submitButton" class="buttonPrimary">Sign out</div>
* </SignOut>
* {:else}
* <span class="notSignedInText">You are not signed in</span>
* <SignIn provider="github"/>
* <SignIn provider="google"/>
* <SignIn>
* <div slot="submitButton" class="buttonPrimary">Sign in</div>
* </SignIn>
* <SignIn provider="facebook"/>
* {/if}
* </div>
* ```
*
* `<SignIn />` and `<SignOut />` are components that `@auth/sveltekit` provides out of the box - they handle the sign-in/signout flow, and can be used as-is as a starting point or customized for your own components.
* To set up the form actions, we need to define the files in `src/routes`:
*
* ```ts title="src/routes/signin/+page.server.ts"
* import { signIn } from "../../auth"
* import type { Actions } from "./$types"
* export const actions: Actions = { default: signIn }
* ```
*
* ```ts title="src/routes/signout/+page.server.ts"
* import { signOut } from "../../auth"
* import type { Actions } from "./$types"
* export const actions: Actions = { default: signOut }
* ```
*
* These routes are customizeable with the `signInPage` and `signOutPage` props on the respective comopnents.
*
* ### Client-Side
*
* We also export two methods from `@auth/sveltekit/client` in order to do client-side sign-in and sign-out actions.
*
* ```ts title="src/routes/index.svelte"
* import { signIn, signOut } from "@auth/sveltekit/client"
*
* <nav>
* <p>
* These actions are all using the methods exported from
* <code>@auth/sveltekit/client</code>
* </p>
* <div class="actions">
* <div class="wrapper-form">
* <button on:click={() => signIn("github")}>Sign In with GitHub</button>
* </div>
* <div class="wrapper-form">
* <button on:click={() => signIn("discord")}>Sign In with Discord</button>
* </div>
* <div class="wrapper-form">
* <div class="input-wrapper">
* <label for="password">Password</label>
* <input
* bind:value={password}
* type="password"
* id="password"
* name="password"
* required
* />
* </div>
* <button on:click={() => signIn("credentials", { password })}>
* Sign In with Credentials
* </button>
* <button on:click={() => signOut()})}>
* Sign Out
* </button>
* </div>
* </div>
* </nav>
* ```
*
* ## Managing the session
*
* The above example checks for a session available in `$page.data.session`, however that needs to be set by us somewhere.
Expand Down Expand Up @@ -162,39 +214,42 @@
* - Very easy to modify
*
* The way to handle authorization through the URI is to override your handle hook.
* The handle hook, available in `hooks.server.ts`, is a function that receives ALL requests sent to your SvelteKit webapp.
* You may intercept them inside the handle hook, add and modify things in the request, block requests, etc.
* Some readers may notice we are already using this handle hook for SvelteKitAuth which returns a handle itself, so we are going to use SvelteKit's sequence to provide middleware-like functions that set the handle hook.
* The handle hook, returned from `SvelteKitAuth` in your `src/auth.ts`, is a function that is designed to receive ALL requests sent to your SvelteKit webapp.
* You should export it from `src/auth.ts` and import it in your `src/hooks.server.ts`.
* To use multiple handles in your `hooks.server.ts`, we can use SvelteKit's `sequence` to execute all of them in series.
*
* ```ts
* ```ts title="src/auth.ts"
* import { SvelteKitAuth } from '@auth/sveltekit';
* import GitHub from '@auth/sveltekit/providers/github';
* import { GITHUB_ID, GITHUB_SECRET } from '$env/static/private';
*
* export const { handle, signIn, signOut } = SvelteKitAuth({
* providers: [GitHub]
* }),
* ```
*
* ```ts title="src/hooks.server.ts"
* import { redirect, type Handle } from '@sveltejs/kit';
* import { handle: authenticationHandle } from './auth';
* import { sequence } from '@sveltejs/kit/hooks';
*
* async function authorization({ event, resolve }) {
* // Protect any routes under /authenticated
* if (event.url.pathname.startsWith('/authenticated')) {
* const session = await event.locals.getSession();
* if (!session) {
* throw redirect(303, '/auth');
* }
* }
*
* // If the request is still here, just proceed as normally
* return resolve(event);
* async function authorizationHandle({ event, resolve }) {
* // Protect any routes under /authenticated
* if (event.url.pathname.startsWith('/authenticated')) {
* const session = await event.locals.getSession();
* if (!session) {
* // Redirect to the signin page
* throw redirect(303, '/auth/signin');
* }
* }
*
* // If the request is still here, just proceed as normally
* return resolve(event);
* }
*
* // First handle authentication, then authorization
* // Each function acts as a middleware, receiving the request handle
* // And returning a handle which gets passed to the next function
* export const handle: Handle = sequence(
* SvelteKitAuth({
* providers: [GitHub({ clientId: GITHUB_ID, clientSecret: GITHUB_SECRET })]
* }),
* authorization
* );
* export const handle: Handle = sequence(authenticationHandle, authorizationHandle)
* ```
*
* :::info
Expand Down

0 comments on commit 8cc2a0f

Please sign in to comment.