npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@ak4zh/auth-helpers-sveltekit

v0.7.10

Published

A collection of framework specific Auth utilities for working with Supabase.

Downloads

9

Readme

@supabase/auth-helpers-sveltekit (BETA)

This submodule provides convenience helpers for implementing user authentication in SvelteKit applications.

Installation

Using npm:

npm install @supabase/auth-helpers-sveltekit

# Main component for Svelte based frameworks (optional but recommended)
npm install @supabase/auth-helpers-svelte

Using yarn:

yarn add @supabase/auth-helpers-sveltekit

# Main component for Svelte based frameworks (optional but recommended)
yarn add @supabase/auth-helpers-svelte

This library supports the following tooling versions:

  • Node.js: ^16.15.0

Getting Started

Configuration

Set up the fillowing env vars. For local development you can set them in a .env file. See an example here.

# Find these in your Supabase project settings > API
VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_ANON_KEY=your-anon-key

SupabaseClient and SupaAuthHelper component setup

We will start off by creating a db.ts file inside of our src/lib directory. Now lets instantiate our supabaseClient by using our createSupabaseClient function from the @supabase/auth-helpers-sveltekit library.

// src/lib/db.ts
import { createSupabaseClient } from '@supabase/auth-helpers-sveltekit';

const { supabaseClient } = createSupabaseClient(
  import.meta.env.VITE_SUPABASE_URL as string,
  import.meta.env.VITE_SUPABASE_ANON_KEY as string
);

export { supabaseClient };

Edit your __layout.svelte file and add import the SupaAuthHelper component, the supabaseClient we just instantiated and the session store.

// src/routes/__layout.svelte
<script>
import { session } from '$app/stores';
import { supabaseClient } from '$lib/db';
import { SupaAuthHelper } from '@supabase/auth-helpers-svelte';	
</script>

<SupaAuthHelper {supabaseClient} {session}>
  <slot />
</SupaAuthHelper>

Hooks setup

Our hooks.ts file is where the heavy lifting of this library happens, we need to import our function to handle the sign in, signing out and cookie creation phase. we can import all the hooks using handleAuth function and destructure its returned data.

// src/hooks.ts
import { handleAuth } from '@supabase/auth-helpers-sveltekit';
import type { GetSession, Handle } from '@sveltejs/kit';
import { sequence } from '@sveltejs/kit/hooks';

export const handle: Handle = sequence(...handleAuth());

export const getSession: GetSession = async (event) => {
  const { user, accessToken, error } = event.locals;
  return { 
    user, 
    accessToken, 
    error
  }
}

These will create the handlers under the hood that perform different parts of the authentication flow:

  • /api/auth/callback: The UserHelper forwards the session details here every time onAuthStateChange fires on the client side. This is needed to set up the cookies for your application so that SSR works seamlessly.
  • /api/auth/user: You can fetch user profile information in JSON format.
  • /api/auth/logout: You can logout the user.

Typings

In order to get the most out of TypeScript and its intellisense, you should import our types into the app.d.ts type definition file that comes with your SvelteKit project.

// src/app.d.ts
/// <reference types="@sveltejs/kit" />
// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
declare namespace App {
  interface UserSession {
    user: import('@supabase/supabase-js').User;
    accessToken?: string;
  }
  
  interface Locals extends UserSession {
    error: import('@supabase/supabase-js').ApiError;
  }

  interface Session extends UserSession {}
  
  // interface Platform {}
  // interface Stuff {}
}

Signing out

This library has provided a dedicated endpoint for you to use to sign a user out. This endpoint will sign the user out of the Gotrue server, clear the cookies that were set when the user logged in and redirect the user to a configurable path.

The logout handler endpoint is /api/auth/logout, this will take a GET request which means it can be used as the href for a normal a tag in your html.

<a href="/api/auth/logout">Sign out</a>

Logout handler configuration

In your src/hooks.ts file the logout handler is already setup and you can configure the redirect path from here.

By default the redirect path after logging out will be /.

export const handle = sequence(...handleAuth({ 
  logout: { returnTo: '/auth/signin' }
}));

Basic Setup

You can now determine if a user is authenticated on the client-side by checking that the user object returned by the $session store is defined.

// example
<script>
import { session } from '$app/stores';
</script>

{#if !$session.user}
  <h1>I am not logged in</h1>
{:else}
  <h1>Welcome {$session.user.email}</h1>
  <p>I am logged in!</p>
{/if}

Client-side data fetching with RLS

For row level security to work properly when fetching data client-side, you need to make sure to import the { supabaseClient } from @supabase/auth-helpers-sveltekit and only run your query once the user is defined client-side in the $session:

<script>
import Auth from 'supabase-ui-svelte';
import { error, isLoading } from '@supabase/auth-helpers-svelte';
import { supabaseClient } from '$lib/db';
import { session } from '$app/stores';

let loadedData = [];
async function loadData() {
  const { data } = await supabaseClient.from('test').select('*').single();
  loadedData = data
}

$: {
  if ($session.user && $session.user.id) {
    loadData();
  }
}
</script>

{#if !$session.user}
  {#if $error}
    <p>{$error.message}</p>
  {/if}
  <h1>{$isLoading ? `Loading...` : `Loaded!`}</h1>
  <Auth
    supabaseClient={supabaseClient}
    providers={['google', 'github']}
  />
{:else}
  <a href=="/api/auth/logout">Sign out</a>
  <p>user:</p>
  <pre>{JSON.stringify($session.user, null, 2)}</pre>
  <p>client-side data fetching with RLS</p>
  <pre>{JSON.stringify(loadedData, null, 2)}</pre>
{/if}

Server-side data fetching with RLS

For row level security to work in a server environment, you need to inject the request context into the supabase client:

<!-- src/routes/profile.svelte -->
<script>
export let user;
export let data;
</script>

<div>Protected content for {user.email}</div>
<pre>{JSON.stringify(data, null, 2)}</pre>
<pre>{JSON.stringify(user, null, 2)}</pre>
// src/routes/profile.ts
import { supabaseServerClient, withApiAuth } from "@supabase/auth-helpers-sveltekit";
import type { RequestHandler } from "./__types/profile";

interface TestTable {
  id: string;
  created_at: string;
}

interface GetOutput {
  user: User;
  data: TestTable[];
}

export const GET: RequestHandler<GetOutput> = async ({ locals }) =>
  withApiAuth(
    {
      redirectTo: "/",
      user: locals.user
    },
    async () => {
      const { data } = await supabaseServerClient(session.accessToken)
      	.from<TestTable>("test")
	.select("*");

      return {
        body: {
          user: locals.user,
          data
        }
      };
    }
  );

Protecting API routes

Wrap an API Route to check that the user has a valid session. If they're not logged in the handler will return a 303 and redirect header.

// src/routes/api/protected-route.ts
import { supabaseServerClient, withApiAuth } from "@supabase/auth-helpers-sveltekit";
import type { RequestHandler } from "./__types/protected-route";

interface TestTable {
  id: string;
  created_at: string;
}

interface GetOutput {
  data: TestTable[];
}

export const GET: RequestHandler<GetOutput> = async ({ locals, request }) =>
  withApiAuth({ user: locals.user }, async () => {
    // Run queries with RLS on the server
    const { data } = await supabaseServerClient(request).from("test").select("*");

    return {
      status: 200,
      body: { data }
    };
  });

If you visit /api/protected-route without a valid session cookie, you will get a 303 response.