DEV Community

Discussion on: FullStack JWT Authentication and Authorization System with Django and SvelteKit - Part 5

 
sirneij profile image
John Owolabi Idogun

Sadly, there is no much resource online for that aside the example in Real World Svelte app. But I will try to explain it here. I will assume you are using TypeScript and that my user type is like:

export interface Token {
    refresh: string;
    access: string;
}
export interface User {
    id?: string;
    email?: string;
    username?: string;
    tokens?: Token;
    full_name?: string;
}
Enter fullscreen mode Exit fullscreen mode

If this type declaration is in src/lib/types/user.interface.ts, I can then import it to app.d.ts and make the Session typed as follows:

import type { User } from '$lib/types/user.interface';
declare global {
    declare namespace App {
        interface Session {
            user: User;
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Then in your login page, you first ensure that the user is not logged in by having this load function:

<script context="module" lang="ts">
    export const load: Load = async ({ session }) => {
        if (!isEmpty(session.user)) {
            return {
                status: 302,
                redirect: '/'
            };
        }
        return {};
    };
</script>
...
Enter fullscreen mode Exit fullscreen mode

isEmpty is a function that checks whether or not an object is empty. An implementation is:

export const isEmpty = (obj) => {
    if (obj === undefined || obj === null) {
        obj = {};
    }
    return Object.keys(obj).length === 0;
};
Enter fullscreen mode Exit fullscreen mode

In the load function, we ensure that a logged in user can't re-login. In the other script tag in the login component and immediately after a user successfully logs in, you can then set the user in the session:

...
// Code that logs user in. After a successfully login attempt
$session.user = responseFromTheBackend;
...
Enter fullscreen mode Exit fullscreen mode

Since session is a store shipped with SvelteKit, we used the auto-subscription sign, $ to access and set the user properties to the response gotten from the backend after the user signs in. Which means the backend must return the user's data as declared in:

export interface User {
    id?: string;
    email?: string;
    username?: string;
    tokens?: Token;
    full_name?: string;
}
Enter fullscreen mode Exit fullscreen mode

After setting this, on every protected page, you can have a load function such as:

<script context="module" lang="ts">
    export const load: Load = async ({ session }) => {
        if (isEmpty(session.user)) {
            return {
                status: 302,
                redirect: <login_url>
            };
        }
    };
</script>
Enter fullscreen mode Exit fullscreen mode

This time, it doesn't go back to the backend to fetch user's data. Instead, it gets the user data stored in the session store and validates the requests made by the user. The session store can be imported like:

import { session } from '$app/stores';
Enter fullscreen mode Exit fullscreen mode

Hope this helps.

Thread Thread
 
ijsucceed profile image
Jeremy Ikwuje • Edited

Yeah, thanks for taking the time. Though I don't write Typescript, but I can understand what you're trying to do.