supertokens-node
supertokens-node copied to clipboard
Increasing the Usability of SuperTokens in SSR Frameworks
Problem / Motivation
As more SSR frameworks come out (e.g., SolidStart, SvelteKit, etc.), I'm realizing that a lot of auth tools -- even some of Auth0's tools -- are restricted by the fact that they're expecting to be run directly on some kind of server (e.g., an express server). And because of this, they often only supply tools that are compatible with Express (or similar) middleware.
Of course, web devs will be using servers. But many popular SSR frameworks try to abstract all of the server complications away. This makes it hard (if not impossible) to apply the security logic which SuperTokens supplies because there's no way to directly apply regular Express middleware with these SSR frameworks. These frameworks have "middleware-like" logic that can be leveraged; but oftentimes, this logic is incompatible with "real"/"standard" middleware that auth tools expect.
Since this more or less seems to have been a problem for other similar auth options so far, if SuperTokens were able to provide a way to integrate with these frameworks universally, it would have an edge over the other options -- at least as far as the crazy JS ecosystem is concerned.
Examples of Incompatible Frameworks
Svelte Kit server handles are I think the closest thing we get to logic that runs for every request before SSR is performed. But it only exposes the Request through their concept of an event argument.
Solid Start is similar, only exposing middleware-like logic through a createHandler function. Again, the original Request is put behind an event argument.
Technically speaking, even other options like Next.js are incompatible. But the SuperTokens team has (thankfully) provided a solution to that problem so that the devs don't have to worry about it. But if there were reusable functions instead of limited middlewares, life would be a lot easier. (And the SuperTokens team would have less packages to maintain and less framework complexities to worry about.)
Potential Solutions
Overall, I think having some kind of function(s) or handler(s) makes sense. It's just that this function/hander shouldn't strictly follow the formula of a some kind of middleware. Instead, we can use a general handler, like SuperTokens.handleRequest (or whatever). This function/handler can take the ~~Request object~~ specific Request information required alone as an input. (It shouldn't accept a full Request object as an argument, nor should it receive a Response as an argument at all.) And it can return whatever makes the most sense... It can return a Response object, it can return only the Response Headers that need to be given, it can return the error state, some combination thereof... etc. But this function will return some kind of "state" that's sufficient enough to use the auth logic and yet general enough to be used in any SSR framework.
I guess it's up to SuperTokens to decide how much things should be split out. For instance, there could be individual handleRequest, handleRequestErrors, and similar functions. Or those individual functions could be split into even smaller pieces to give more flexibility to developers. (Do they need that much flexibility?) Similarly, for things like login/signup routes... functions could be provided explicitly, or examples could be given on how to leverage existing SuperTokens functionality to accomplish the desired functions (hopefully easily).
As an example to make this clear
// In some API route file in an SSR framework
function POST(request: Request): Response {
const supertokensData = SuperTokens.handleLogin(request);
// Build a `Response` object from the supertokensData and perhaps other logic within this route handler
return builtResponse;
}
and
// In some API route file in an SSR framework
function POST(request: Request): Response {
// Derive supertokensData from various SuperTokens Node functions
// ...
const builtResponse = buildResponseFromSuperTokensData(derivedSuperTokensData);
return builtResponse;
}
would be preferred over
// In some Express Server file
app.use(middleware());
for these various SSR frameworks.
I don't know how feasible this is. Maybe it's already possible? (Maybe it isn't at all? :sweat_smile:) I guess we can also flesh these ideas out through conversation. But if there was a way to accomplish this, that'd be great. And I think it would give an edge to SuperTokens in JS-land.
Kinda like with the remix-supertokens example of creating the frontend UI from scratch, as long as there's a consistent base example out there somewhere on how to setup the functionality clearly/easily given any server/SSR framework, every user's needs are met. (Even if it's a tiny bit more effort.) This is optimal compared to users being left with no options for the framework of their choice.