skip to Main Content

I have a Django application with authenticated (logged-in) users.
UPDATE: using the built-in django authentication.

I have another (Svelte) application using Auth.js (https://authjs.dev) for authentication, currently set up with github/facebook/linkedin.

Now I want to send a user from the Django application to the Svelte application, and automagically (i) create the user in the Svelte application if they don’t exist, and (ii) log them in to the Svelte application.

I want the end-user experience to be like a regular redirect from one page to the other staying logged-in in both places.

I’m stuck at the part where the user arrives in the Svelte application and I need to create a session. Does Auth.js have any way of doing this without going through a "provider"?

What I have so far is (routes/api/sso/+server.ts):

import { redirect } from '@sveltejs/kit'

export async function GET({url, locals, cookies}) {  // should perhaps be POST..?
    // TODO: validate request..

    // where to go next?
    const next = url.searchParams.get('next')
    if (!next) throw new Error("next is required")

    // who are we logging in?
    const usr = get_or_create(url.searchParams('username')) // and name/email/image/etc.

    // mimic auth.js login behavior...
    const session_token = create_new_session_token()
    locals.session = {
        id: session_token,
        user: {name: usr.name, email: usr.email, image: usr.image}
        expires: new Date(Date.now() + 1000 * 60 * 60 * 2) // two hours
    }
    locals.user = usr
    // ..this might be the only line needed (I'm guessing auth.js will set locals.{session,user} next time it receives a request)?
    cookies.set("authjs.session-token", session_token, {path: "/", httpOnly: true, secure: true, sameSite: "strict"})

    return redirect(307, next)
}

2

Answers


  1. I am not sure how you are maintaining the users in backend. Both your Django and Svelet app should be referring to the same user table on authjs. In that case simply passing the auth Headers should be sufficient.

    Login or Signup to reply.
  2. The Django app generates a signed, secure token and redirects the user to the Svelte app, passing the token as part of the URL or a POST body. The Svelte app validates the token with Django.

    To implement this use a secure method to generate a token in Django. You can use itsdangerous, a built-in Django signing module, or JWTs.

    In your Svelte app’s SSO endpoint (routes/api/sso/+server.ts), create a session for the user using Auth.js’s session management.

    Auth.js sessions rely on cookies. After creating or updating the user in the Svelte app, you can use Auth.js’s built-in cookies to manage the session.

    Here are the amended codes:

    import { redirect } from '@sveltejs/kit';
    import { verifyTokenWithDjango } from '$lib/auth'; // Token validation helper
    import { prisma } from '$lib/server/prisma'; // Database helper
    import { createSession } from '$lib/server/auth'; // Auth.js session helper
    
    export async function GET({ url, cookies }) {
        // Extract query parameters
        const token = url.searchParams.get('token');
        const next = url.searchParams.get('next') || '/';
    
        // Validate inputs
        if (!token) throw new Error('SSO token is required');
        if (!next) throw new Error('The "next" parameter is required');
    
        // Step 1: Validate the token with Django
        const userInfo = await verifyTokenWithDjango(token);
        if (!userInfo) {
            throw new Error('Invalid or expired SSO token');
        }
    
        // Extract user info from the validated token
        const { email, username, name, image } = userInfo;
    
        // Step 2: Create or update the user in database
        const user = await prisma.user.upsert({
            where: { email },
            update: { username, name, image },
            create: { email, username, name, image }
        });
    
        // Step 3: Create a session using Auth.js - compatible logic
        const { sessionToken, sessionExpires } = await createSession(user, cookies);
    
        // Step 4: Set the session token in the cookies
        cookies.set('authjs.session-token', sessionToken, {
            path: '/',
            httpOnly: true,
            secure: true,
            sameSite: 'strict',
            expires: sessionExpires
        });
    
        // Step 5: Redirect to next page
        return redirect(307, next);
    }
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search