Search code examples
authenticationwebstoragesveltesveltekit

How to check authentication in SvelteKit?


I want to check if the user is logged in when they visit the route /login and, if so, redirect them to /. The same happens vice versa if they are not logged in as well.

I want to put something like:

export async function load() {
    const res = await fetch("[endpoint]", {
        headers: {
            "Authorization": `Bearer ${localStorage.jwt}`
        },
        credentials: "include"
    });
    const json = await res.json();
    return {
        logged_in: json.logged_in
    };
}

in my +page.js (or +page.server.js?) but this doesn't work as it says localStorage is undefined.

How should I go about doing this?


Solution

  • LocaleStorage in Sveltekit is a bit tricky, but there are ways around it, like checking to see if your code is being executed on the client's browser, like so:

    import { browser } from '$app/env'
    
    export async function load(){
        if (browser) {
            // Do stuff here
            ...
        }
        ...
    }
    

    A solution that's worked for me is chucking this code into the <script context="module"> of a base __layout.svelte that every layout inherits from.

    For instance, you could have a __layout.svelte that consists of nothing more than this code. Building off of what Stephane pointed out, if you don't want to use cookies (e.g. a jwt token with a very limited lifespan) you could use session storage;

    <script context="module">
    export async function load({ fetch, session }) {
        const res = await fetch("[endpoint]", {
            headers: {
                "Authorization": `Bearer ${session.jwt}`
            },
            credentials: "include"
        });
        const json = await res.json();
        return {
            logged_in: json.logged_in
        };
    }
    </script>
    
    <slot />
    

    (You can read more about load() here)

    And then have other layouts that inherit this layout by having a layout like __layout-auth@default.svelte. You can read more about named layouts here.