Authentication in SvelteKit

Authentication in SvelteKit

The full tutorial on implementing an authentication system in SvelteKit

ยท

4 min read

SvelteKit - it's like NextJS, but for Svelte. In this article, I'll teach you everything you need to know about authentication with server-side rendering in SvelteKit.

This does not include things like a login with Google or database stuff - it's about the basic realization of an authentication system with serverside rendering. We'll use a simple API endpoint in SvelteKit to allow or deny access based on a simple if-statement.

Setup a new SvelteKit project

Use the npx command to get started with a new project:

npm init svelte@next sveltekit-auth
# In this example I selected sceleton project and said NO to TypeScript, YES to ESLint and YES to Prettier
cd sveltekit-auth
npm install

# Open the website in the browser:
npm run dev -- --open

Because we're going to store the authentication details (e.g. session token) in the cookies, let's also add the cookie package:

npm i cookie

The Authentication hook

Most likely you want to validate the users session on every request to the website. So instead of implementing this logic on every page, we'll create a hook that'll be executed on every page request. Inside of this hook, we can add data to the request that we can access later in our code (e.g. the pages themselves).

To create a new hook, let's create a new file:

// /src/hooks.js

import * as cookie from "cookie"

export async function getSession({ headers }) {
    const cookies = cookie.parse(headers.cookie || "")

    try {
        if(cookies.sessionid) { // Check for a sessionID
            const sessionid = cookies.sessionid // Get the sessionID
            // ! This is for this example ONLY. In production, here would be something
            // like a database query to validate the session
            if(sessionid === "session1") {
                return {
                    authenticated: true,
                    isAdmin: true,
                }
            }else if(sessionid === "session2") {
                return {
                    authenticated: true,
                    isAdmin: false,
                }
            }
        }
    }catch(error) {
        console.log(error)
    }

    // By default, the user is not authenticated
    return {
        authenticated: false,
    }
}

What this code does is pretty simple - we're exporting a function that takes the request headers as an argument, because that's where the cookies are stored in. Then we parse the cookie string from the header to a javascript object and check for the cookie we need (sessionid). If this cookie is present, we check for our two test-sessions and return authenticated: true together with the isAdmin boolean. That's just for testing - you'll implement something like a databse query to validate the session.

As you see, we're returning always the authentication boolean, so we can use this later in our code to determinate if the user is logged in or not. You can here also store something like the username or email if needed.

load() method

Now we need a way to get the authentication state. In our pages, we can do that with the load function. That's the function executed on the server when we request the page. Export it in the module context:

<!-- /src/routes/index.svelte -->

<script context="module">

    export async function load({ session }) {
        return {
            props: {
                loggedIn: session.authenticated,
                admin: session?.isAdmin || false,
            }
        }
    }

</script>

<script>

    export let loggedIn, admin

</script>

<p>
    You {loggedIn ? "are" : "are not"} logged in and your rank is {admin ? "admin" : "guest"}.
</p>

This example simply passes the loggedIn and admin status to the page. But that's the point where you can add your own logic and use the authentication state for database queries or redirect the user if it's a private page. You can redirect the user like this:

return {
    status: 403,
    redirect: "/login"
}

Open the page in your browser and you should see the following text:

You are not logged in and your rank is guest.

Pull up the devtools and set the cookie sessionid to session1, now you should see this text:

You are logged in and your rank is admin.

The login and logout components

As I said before, I won't implement a real database or user system in this example. In your login component, the only thing you need to do is to save the sessionID or whatever you need to authenticate the user in the cookies (same name you used in /src/hooks.js). And after the user logged out, remove the cookie.

That's how authentication in SvelteKit generally works. I'll create a more detailed guide with a real database and login system in the future, so make sure to follow my blog or join my newsletter to get notified when the article comes out.

Thank you for reading and have a nice day ๐Ÿค—๐ŸŽ‰

Did you find this article valuable?

Support Linus Benkner by becoming a sponsor. Any amount is appreciated!

ย