Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable Custom Express Server request Data to Be Read by Svelte-Kit (for Auth) #4654

Closed
ITenthusiasm opened this issue Apr 18, 2022 · 9 comments
Labels
feature request New feature or request p1-important SvelteKit cannot be used by a large number of people, basic functionality is missing, etc.
Milestone

Comments

@ITenthusiasm
Copy link

ITenthusiasm commented Apr 18, 2022

Describe the problem

Split from #2051 after reading @benmccann's comment and #2051 (comment).

The real issue for me here is regarding authentication/authorization. A particularly common solution for this is Auth0. The new Open Source cool kid on the block is SuperTokens. When using Express middleware, solutions like these (and others) typically have a habit of adding data to the request object. For example, Auth0 gives us req.oidc, and SuperTokens gives us req.session. With this info we can determine if a user is authenticated and act accordingly.

According to Auth0, it's safer to handle these things on the backend. Consequently, for web apps, Auth0 recommends the Authorization Code Flow. A similar approach would need to be used for other libraries/tools/solutions.

Unfortunately, from what I can tell, Svelte Kit has no way of accessing the information that these tools provide on the backend, which means there's no way to protect your routes on the backend. I've been trying at this for 2 or 3 weeks now (as I've had time) and haven't found a practical or even a jank solution to this problem.

Describe the proposed solution

A simple solution would be to provide a way for data tacked onto the request object to be given to Svelte Kit so that its handle function and/or endpoints can read it. From the comment that I mentioned earlier from Ben, it seems like this is possible?

Alternatives considered

Theoretically, if someone obtained extensive knowledge about the internals of an auth solution, a "Svelte-Kit-friendly" approach could be crafted instead. But this is clearly impractical and would have to be done for each and every auth solution. The research has been exhausting for me and I've gotten nowhere.

Theoretically, life could also be easier if the existing auth solutions provided approaches that were more like functions that returned information? But again, that would have to be done for each solution, and I don't know how viable that is.


Invalid Alternatives

Just in case they're brought up...

1) I don't want to use Authorization Code Flow with PKCE, or any other browser-only solutions. If all of the approaches were equally secure, then this issue would not matter. But seeing as those familiar with auth highly recommend handling this stuff on the backend, it's unfair to require devs to sacrifice security just for the sake of preference. In some (if not many) cases, this approach would also thwart SSR.

2) Requiring devs to implement their own separate auth solutions that are Svelte-Kit-friendly is not a valid option either. User security is a big deal. So if a dev is lacking knowledge, and if solutions are available from people who have worked out many kinks and who continue to make improvements, then it makes more sense to use those.

Open to any valid Svelte-Kit-friendly solutions that get auth working on the backend though!

Importance

i cannot use SvelteKit without it

Additional Information

If it's of use, here's an example of using Auth0 with ExpressJS web apps: https://auth0.com/docs/quickstart/webapp/express. (This is imagined to be an actual web app, not a mere collection of backend APIs.)

And here's an example from SuperTokens: https://supertokens.com/docs/emailpassword/common-customizations/verify-session.

It seems Remix has their own solution for this problem too if it helps.

@noboomu
Copy link

noboomu commented Apr 19, 2022

I honestly don’t think that’s something the kit team will resolve. There are scores of issues requesting similar functionality over the last few years and none of them ever provided a viable solution for those using express. We chose sapper and svelte 3 years ago to build out an e-commerce platform with deep express integration. The performance was better than the competition at the time, but now we are stuck using sapper and really dated versions of svelte. Currently we are considering abandoning svelte altogether given the incredibly frustrating experience we have faced attempting to migrate. We are not going serverless for numerous reasons and the number of hours we’ve wasted trying to integrate kit with our node server is heartbreaking. Unless I am deeply mistaken, there is no room for folks with an existing express backend in sveltekit’s future. I apologize in advance for the rant, but your issue gave me the clearest opportunity to vent my frustration.

@ITenthusiasm ITenthusiasm changed the title Enable Custom Express Server request Data to Be Read by Svelte-Kit Enable Custom Express Server request Data to Be Read by Svelte-Kit (for Auth) Apr 19, 2022
@benmccann benmccann added this to the 1.0 milestone Apr 21, 2022
@benmccann benmccann added the feature request New feature or request label Apr 21, 2022
@unlocomqx
Copy link

unlocomqx commented Apr 25, 2022

I had a similar issue with Shopify Auth. One of the solutions I tried was creating a custom svelte-kit server using express. something like this.
The difficulty is that you also need to inject the middleware in dev mode as well . So that's a path you can follow if you didn't already try it.
I ultimately rewrote the Shopify middleware but I'm not gonna suggest you do the same.

@ITenthusiasm
Copy link
Author

I ultimately rewrote the Shopify middleware but I'm not gonna suggest you do the same.

Yeah that was the problem I wanted to avoid, as I mentioned in the Alternatives Considered section. Once someone is forced to go down that road, it creates a pretty bad developer experience. And even if one person figures out a hack, it still leaves everyone else in the dark (for each and every auth middleware too).

This is honestly a problem that often seems to be overlooked in SSR frameworks like Next.js, Nuxt.js, etc. Svelte Kit was close, but they still blocked out the ability to accomplish these kinds of things... leaving the problem to remain. Remix ultimately seems to be the first popular option to resolve this problem.

Since this issue got added to Milestones, I'm hopeful that it'll get resolved. Then Svelte Kit will (as far as I know) have a unique advantage over several other frameworks (e.g., Next.js).

@itssumitrai
Copy link

itssumitrai commented Apr 29, 2022

While its not a solution, but I also had a situation where I needed to use existing express middlewares into my Sveltekit app. I realized that I can't add the middleware to my custom express server, cause Sveltekit doesn't use the same request obejct. But I found a workaround to use express middlewares in my Sveltekit app using hooks. Hope it works for you as well.

// hooks.js
import middlewares from './middlewares'; // export your express middlewares as an array here

export const handle = sequence(
    async ({ event, resolve }) => {
        // polyfill request.query for Express middlewares
        if (!event.request?.query) {
            event.request.query = Object.fromEntries(new URL(event.request.url).searchParams);
        }
        // polyfill request.get for Express middlewares
        if (!event.request?.get) {
            event.request.get = (name) => event.request.headers.get(name);
        }
        return await resolve(event);
    },
    ...middlewares.map((middleware) => {
        return async ({ event, resolve }) => {
            return await new Promise((next) => middleware(event.request, {}, next)).then(() =>
                resolve(event)
            );
        };
    }),
    async ({ event, resolve }) => {
        const response = await resolve(event);
        return response;
    }
);


@ITenthusiasm
Copy link
Author

But I found a workaround to use express middlewares in my Sveltekit app using hooks. Hope it works for you as well.

Unfortunately, that workaround doesn't quite do what I need it to do. I don't know what the rules are for updating the Response object, but my problem is needing request information from the node server itself so that I can generate an appropriate response.

Your solution doesn't seem to "need" anything that comes from Express. (You could probably skip the polyfilling if you had info from Express. But you're still able to access/create the data you need without using Express.) Even so, thanks for sharing! Perhaps it might help someone else who stumbles across this issue. 🙏🏾

@benmccann benmccann added the p1-important SvelteKit cannot be used by a large number of people, basic functionality is missing, etc. label Jul 29, 2022
@rmunn
Copy link
Contributor

rmunn commented Aug 17, 2022

@ITenthusiasm - Now that #5778 (which implements #5748) is merged, and +server.js endpoint handler functions get access to a Request object, does this satisfy your needs? Or should this issue remain open because there's something else you need that the Request object doesn't provide?

@Conduitry
Copy link
Member

This is asking for a way to expose data from the underlying Express request object. It wouldn't be affected by recent changes, which still just give you access to the Web API Request object.

@ITenthusiasm
Copy link
Author

Thanks for checking in though!

@Rich-Harris
Copy link
Member

This should have been closed when #8171 was merged

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request New feature or request p1-important SvelteKit cannot be used by a large number of people, basic functionality is missing, etc.
Projects
None yet
Development

No branches or pull requests

8 participants