Monday, July 25, 2022
HomeWordPress DevelopmentSvelteKit with Supabase Auth Helpers

SvelteKit with Supabase Auth Helpers


Supabase has not too long ago introduced the revamped auth helpers for Supabase with SvelteKit help.



What are Auth Helpers?

In keeping with Supabase one of many challenges has been making a easy expertise for server-side rendering (SSR) environments. Auth Helpers are a group of framework-specific utilities for Supabase Auth. They let you implement safe functions with little effort. These libraries embrace features for shielding API routes and pages in your functions.



How you can use Supabase Auth Helpers in SvelteKit Projet?



TL;DR

Simply set up these two npm packages:

npm set up @supabase/auth-helpers-sveltekit
npm set up @supabase/auth-helpers-svelte
Enter fullscreen mode

Exit fullscreen mode



Detailed Tutorial



Set Up SvelteKit Mission

We are going to attempt to have a minimal naked bone mission. You might be free so as to add any styling,sort checking and many others later. Supabase has fairly good examples utilizing TypeScript out there right here.

Let identify the mission SvelteKitSupabaseAuthApp.
Simply use the Skeleton mission, no TypeScript, no ESLint, no Prettier, no Playwright.

npm create svelte@newest SvelteKitSupabaseAuthApp
cd SvelteKitSupabaseAuthApp
npm set up
Enter fullscreen mode

Exit fullscreen mode



Set up Supabase Auth Helpers for SvelteKit

npm set up @supabase/auth-helpers-sveltekit
npm set up @supabase/auth-helpers-svelte
Enter fullscreen mode

Exit fullscreen mode



Set Up Supabase Mission

  • Login in Supabase and create a brand new mission on the Supabase dashboard.
  • Go to Authentication > Settings part and alter Person Periods – Website URL from http://localhost:3000 to http://localhost:3000/5173 and save. This can be a localhost deal with the place SvelteKit serves the mission in developer mode. This transformation was launched with Vite 3.
  • Go to Settings > API part and get the URL and anon key of your mission.
  • Return to your SvelteKitSupabaseAuthApp mission and in its root create a brand new .env file. Exchange VITE_SUPABASE_URL with the URL from earlier step and VITE_SUPABASE_ANON_KEY with anon key from earlier step:
# .env
# Replace these with your Supabase particulars from your mission settings > API
VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_ANON_KEY=your-anon-key
Enter fullscreen mode

Exit fullscreen mode



Supabase Consumer Creation

In src folder create a brand new folder lib and on this lib folder create a brand new file sb.js, right here we create supabaseClient utilizing our credentials from .env finish export the supabaseClient so we will use its auth strategies in our utility.

We are going to use login with e mail on this app. Supabase sends affirmation e mail mechanically when a person indicators ups.

// lib/sb,js
import { createSupabaseClient } from '@supabase/auth-helpers-sveltekit';

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

export { supabaseClient };

Enter fullscreen mode

Exit fullscreen mode



Hooks

In SvelteKit hook permits us to make use of two essential features, a deal with operate and a getSession operate. The deal with operate runs each time the SvelteKit server receives a request. The getSession operate takes the occasion object and returns a session object that’s accessible on the consumer, so we will for instance entry knowledge regarding person and cookies.

In src folder create a brand new file hooks.js

// src/hooks.js
import { handleAuth } from '@supabase/auth-helpers-sveltekit';
import { sequence } from '@sveltejs/equipment/hooks';

export const deal with = sequence(
    ...handleAuth({
        cookieOptions: { lifetime: 1 * 365 * 24 * 60 * 60 }
    })
);

export const getSession = async (occasion) => {
    const { person, accessToken } = occasion.locals;
    return {
        person,
        accessToken
    };
};

Enter fullscreen mode

Exit fullscreen mode



Structure

In src/routes/ folder create a brand new format file __layout.svelte so we can’t solely have a easy format however extra importantly introduce our SupaAuthHelper element.

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

<svelte:head>
    <title>Electronic mail and Password Demo - Supabase Auth Helpers</title>
</svelte:head>

<SupaAuthHelper {supabaseClient} {session}>
    <essential>
        <div>
            <h2>
                <a href="/">Supabase Auth Helpers Demo</a>
            </h2>

            <slot />

            <div>
                {#if $session?.person?.id}
                    <a href="/api/auth/logout">Signal out</a>
                {/if}
            </div>
        </div>
    </essential>
</SupaAuthHelper>

Enter fullscreen mode

Exit fullscreen mode



Enroll Web page and Route

In src/routes/ folder create a brand new file signup,svelte Only a easy sing up type.

// src/routes/signup,svelte
<script>
    export let errors = null;
    export let values = null;
    export let message = null;
</script>

<part>
    <div>
        <h1>Signal up</h1>
        {#if errors}
            <div>{errors.type}</div>
        {/if}
        {#if message}
            <div>{message}</div>
        {/if}
        <type technique="put up">
            <div>
                <label for="e mail">Electronic mail</label>
                <p>
                    <enter
                        id="e mail"
                        identify="e mail"
                        worth={values?.e mail ?? ''}
                        sort="e mail"
                        placeholder="Electronic mail"
                        required
                    />
                </p>
            </div>
            <div>
                <label for="password">Password</label>
                <p>
                    <enter
                        id="password"
                        identify="password"
                        worth={values?.password ?? ''}
                        sort="password"
                        placeholder="Password"
                        required
                    />
                </p>
            </div>
            <div>
                <p>
                    <button>Signal up</button>
                </p>
            </div>
        </type>

        <div>
            <p>
                Already have an account? <a href="/">Signal in</a>
            </p>
        </div>
    </div>
</part>

Enter fullscreen mode

Exit fullscreen mode

In src/routes/ folder create a brand new signup.js file. This endpoint factors present person to /dashboard which is protected person solely web page or supplies sing up knowledge to supabaseClient. We’re additionally including object specifying redirect when consumer clicks affirmation hyperlink in a affirmation e mail that Supabase will ship him/her.

// src/routes/signup.js
import { supabaseClient } from '$lib/sb';

export const GET = async ({ locals }) => {
    // if the person is already logged in, then redirect to the dashboard
    if (locals.person) {
        return {
            standing: 303,
            headers: {
                location: '/dashboard'
            }
        };
    }
    return {
        standing: 200
    };
};

export const POST = async ({ request, url }) => {
    const knowledge = await request.formData();

    const e mail = knowledge.get('e mail');
    const password = knowledge.get('password');

    const errors = {};
    const values = { e mail, password };

    const { error } = await supabaseClient.auth.signUp(
        { e mail, password }, 
        { redirectTo: `${url.origin}/logging-in`}
    );

    if (error) {
        errors.type = error.message;
        return {
            standing: 400,
            physique: {
                errors,
                values
            }
        };
    }

    return {
        standing: 200,
        physique: {
            message: 'Please examine your e mail for a affirmation e mail.'
        }
    };
};

Enter fullscreen mode

Exit fullscreen mode



Log in (index) Web page and Route

In src/routes/ folder change index.svelte with this new one.Only a easy login type.

// src/routes/index.svelte
<script>
    export let errors;
    export let values;
</script>

<part>
    <div>
        <h1>Signal in</h1>
        {#if errors}
            <div>{errors.type}</div>
        {/if}
        <type technique="put up">
            <div>
                <label for="e mail">Electronic mail</label>
                <p>
                    <enter
                        id="e mail"
                        identify="e mail"
                        worth={values?.e mail ?? ''}
                        sort="e mail"
                        placeholder="Electronic mail"
                        required
                    />
                </p>
            </div>
            <div>
                <label for="password">Password</label>
                <p>
                    <enter
                        id="password"
                        identify="password"
                        worth={values?.password ?? ''}
                        sort="password"
                        placeholder="Password"
                        required
                    />
                </p>
            </div>
            <div>
                <p>
                    <button>Signal in</button>
                </p>
            </div>
        </type>

        <div>
            <p>
                Don't have an account? <a href="https://dev.to/signup">Enroll</a>
            </p>
        </div>
    </div>
</part>

Enter fullscreen mode

Exit fullscreen mode

In src/routes/ folder create a brand new index.js file. This endpoint factors present person to /dashboard which is protected person solely web page or supplies login knowledge to supabaseClient, returned session is use for a cookie creation.

//src/routes/index.js
import { supabaseClient } from '$lib/sb';

export const GET = async ({ locals }) => {
    if (locals.person) {
        return {
            standing: 303,
            headers: {
                location: '/dashboard'
            }
        };
    }
    return {
        standing: 200
    };
};

export const POST = async ({ request, url }) => {
    const knowledge = await request.formData();

    const e mail = knowledge.get('e mail');
    const password = knowledge.get('password');

    const headers = { location: '/dashboard' };
    const errors = {};
    const values = { e mail, password };

    const { session, error } = await supabaseClient.auth.signIn({ e mail, password });

    if (error) {
        errors.type = error.message;
        return {
            standing: 400,
            physique: {
                errors,
                values
            }
        };
    }

    if (session) {
        const response = await fetch(`${url.origin}/api/auth/callback`, {
            technique: 'POST',
            headers: new Headers({ 'Content material-Sort': 'utility/json' }),
            credentials: 'same-origin',
            physique: JSON.stringify({ occasion: 'SIGNED_IN', session })
        });

        // TODO: Add helper inside auth-helpers-sveltekit library to handle this higher
        const cookies = response.headers
            .get('set-cookie')
            .break up('SameSite=Lax, ')
            .map((cookie) => {
                if (!cookie.contains('SameSite=Lax')) {
                    cookie += 'SameSite=Lax';
                }
                return cookie;
            });
        headers['Set-Cookie'] = cookies;
    }
    return {
        standing: 303,
        headers
    };
};


Enter fullscreen mode

Exit fullscreen mode



Electronic mail affirmation redirect web page

In src/routes/ folder create a brand new file logging-in@clean.svelte so we will examine if the person redirected after e mail affirmation has been already set in session retailer. We can even present a particular format for this case in a while. Throughout my exams the redirect and session retailer had been fairly quick so this web page could also be seen slightly hardly ever.

src/routes/logging-in@clean.svelte
<script>
    import { session } from '$app/shops';
    import { goto } from '$app/navigation';
    import { web page } from '$app/shops';

    let redirectPath = '/dashboard';

    $: {
        const redirectTo = $web page.url.searchParams.get('redirect');
        if (redirectTo) {
            redirectPath = redirectTo;
        }
        // examine if person has been set in session retailer then redirect
        if ($session?.person?.id) {
            goto(redirectPath);
        }
    }
</script>

<part>
    <div>
        <progress class="progress" max="100" />
    </div>
    <div>
        Signing in from the e mail affirmation hyperlink  ...
    </div>
</part>

<type>
    .progress:indeterminate {
        animation-period: 3.8s;
    }
</type>

Enter fullscreen mode

Exit fullscreen mode



Dashboard Web page and Route – protected customers solely web page

In src/routes/ folder create a brand new file dashboard.svelte the place we show some knowledge about person saved by Supabase,

src/routes/dashboard.svelte 
<script>
    export let person;
</script>

<div>
    <h3>This is protected route accesible solely for ligged customers</h3>
    <p>Hiya person {person.e mail}</p>
</div>
<div>
    <p>Person {person.e mail} particulars:</p>
    <pre>{JSON.stringify(person, null, 2)}</pre>
</div>

Enter fullscreen mode

Exit fullscreen mode

In src/routes/ folder create a brand new dashboard.js file.

src/routes/dashboard.js
import { supabaseServerClient, withApiAuth } from '@supabase/auth-helpers-sveltekit';

export const GET = async ({ locals, request }) =>
    withApiAuth(
        {
            redirectTo: '/',
            person: locals.person
        },
        async () => {
            // const { knowledge } = await supabaseServerClient(request).from('take a look at').choose('*');
            return {
                physique: {
                    // knowledge,
                    person: locals.person
                }
            };
        }
    );

Enter fullscreen mode

Exit fullscreen mode



Electronic mail Affirmation Redirect Structure

In src/routes/ folder create a brand new file __layout-blank.svelte the place we’re having a particular named format for e mail affirmation redirect as talked about earlier.

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

<svelte:head>
    <title>Electronic mail and Password Demo - Supabase Auth Helpers</title>
</svelte:head>

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

Enter fullscreen mode

Exit fullscreen mode

I hope this tutorial was helpful. Large thank to Supabase guys for SvelteKit Auth Helpers, their examples the place true supply for this text. As a result of I’m actually no auth skilled especial y regarding SSR all feedback, corrections or enhancements are welcomed.

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments