logto-io / logto

🧑‍🚀 The better identity infrastructure for developers and the open-source alternative to Auth0.
https://logto.io
Mozilla Public License 2.0
7.44k stars 364 forks source link

feature request: SvelteKit SDK #3008

Open alteregogi opened 1 year ago

alteregogi commented 1 year ago

What problem did you meet?

I was trying to integrate open source Auth to my web app and found logto trying it and have great UI, but no SDK for SvelteKit

Describe what you'd like Logto to have

add support to SvelteKit

j2l commented 1 year ago

yes please! :smile:

gao-sun commented 1 year ago

someone has a sample project: https://github.com/vocamen/svelte-logto

let me know if it helps

j2l commented 1 year ago

Perfect :smile: thanks @gao-sun

jay-dee7 commented 1 year ago

@gao-sun @j2l I have a super early version of sveltekit sdk here:

  1. Repo -> https://github.com/cheqd/logto-js-sdks
  2. NPM Package - https://www.npmjs.com/package/@cntr/sveltekit

Note: This SDK is at alpha stage right now, a lot of it is just hacks

SvelteKit Example Project using this library

https://github.com/jay-dee7/logto-sveltekit-example

The only downside right now is that our version of the sdk assumes all logto logic to be handled at server side plus you manually need to handle the SvelteKit redirect throws but it seems to be working pretty much good for us. When I get some time, I'll rewrite it again from scratch but I'm running short of bandwidth right now.

We use it like this:

// hooks.server.ts

import { LogtoAuthHandler, UserScope } from '@cntr/sveltekit';
export const handle = sequence(
        ...
    LogtoAuthHandler(PUBLIC_LOGTO_APP_ID, PUBLIC_LOGTO_ENDPOINT, [
        UserScope.Email,
        UserScope.Profile,
    ]),
    ...
);

Then handle the signin callback at some endpoint like (/logto/callback)

// src/routes/logot/callback/+server.ts
// also this route is set in logto app instance as the signin redirect url

export const GET = (async ({ locals, url, fetch }) => {
    try {
        await locals.logto.handleSignInCallback(url.toString());
    } catch (err) {
        console.log('ERR_LOGTO_SIGNIN_CALLBACK: ', err);
        throw error(401, {
            message: (err as Error).message,
        });
    }
        //
        more logic here
        //

The only thing is that apis like signout do a redirect and SvelteKit redirects are different than normal navigation. So I'm right now forced to use it like this (Handle the thrown redirect on server, send the location to client and make the client navigate to the location)

// src/routes/apis/signout/+server.ts

export const DELETE = (async ({ url, locals }) => {
    try {
        await locals.logto.signOut(url.origin);
        return new Response(null, { status: 204 });
    } catch (err) {
        if (isSvelteKitRedirect(err)) {
            return new Response(JSON.stringify({ location: err.location }), {
                status: 201,
                headers: { Location: err.location },
            });
        }
    }

    return new Response(JSON.stringify({ error: 'Unhandled exception' }), { status: 500 });
}) satisfies RequestHandler;

I hope this helps

oronoa commented 1 year ago

Can you share a full example please ? not sure where isSvelteKitRedirect comes from ...

jay-dee7 commented 1 year ago

@oronoa isSvelteKitRedirect is a type guard and this is what it is:

import type { Redirect } from '@sveltejs/kit';

export const isSvelteKitRedirect = (val: any): val is Redirect => {
    return val && val.status !== undefined && val.location !== undefined;
};

I'll put the whole thing in an example project and share it here

jay-dee7 commented 1 year ago

@oronoa here's a repository the combines the above comments into a bare-minimum SvelteKit project - https://github.com/jay-dee7/logto-sveltekit-example

oronoa commented 1 year ago

Hi, Thanks for the example, was able to integrate logto to my app using your code, but I'm still confused as to how I'm syncing the logto users to what they do on my app. For example the user now sets some custom property on one of my DB tables like 'color_pref', how do I tell my backend which user this is, I'm used to JWT all around but here I can't see how I get the JWT token for that user.

jay-dee7 commented 1 month ago

@gao-sun Looks like this one is completed now? I just realized that we finally have an official implementation for SvelteKit, super excited about this 🥳 🥳