#Authentication in both component and middleware

5 messages · Page 1 of 1 (latest)

slow leaf
#

After did some search I'm still confused how solid start handles the authentication. In some auth libraries, they are using middleware to protect api routes and actions but not components(middlewares do not get called when route changes). I looked at the auth example, it only applies a simple action, not a layout.
I simply created an auth middleware (from lucia example) and protected component, but I think the solution is not clear.

#

middleware

export default async function authMiddleware(event: FetchEvent) {
    const sessionId =
        getCookie(event.nativeEvent, lucia.sessionCookieName) ?? null;
    if (!sessionId) {
        event.locals.user = null;
        event.locals.session = null;
        return;
    }
    // null when not found in database, expired
    // fresh = true when half of expiration
    const { session, user } = await lucia.validateSession(sessionId);
    if (session && session.fresh) {
        const sessionCookie = lucia.createSessionCookie(session.id);
        setCookie(
            event.nativeEvent,
            sessionCookie.name,
            sessionCookie.value,
            sessionCookie.attributes,
        );
    }
    if (!session) {
        const sessionCookie = lucia.createBlankSessionCookie();
        setCookie(
            event.nativeEvent,
            sessionCookie.name,
            sessionCookie.value,
            sessionCookie.attributes,
        );
    }
    event.locals.user = user;
    event.locals.session = session;
}

protected component

const getUser = cache(async () => {
    "use server";
    const event = getRequestEvent();
    const user = event?.locals.user;
    if (user) {
        return user;
    } else {
        // return null
        throw redirect("/login");
    }
}, "get-user");
export const ProtectedRoute = (props: ParentProps) => {
    const user = createAsync(() => getUser());
    if (user()) {
        return props.children;
    } else {
        return <Navigate href="/login" />;
    }
};

Problems:

  1. If session or user is null, middleware should return a redirect to login page, but redirect function or sendRedirect(from vinxi) cause too many redirect error. If the middleware logic is correct, how to redirect in middleware?
#
  1. In protected component, I can easily redirect in server functions. Doing it again in component with Navigate is definitely not necessary. Should I just return null in the function?
valid geyser
#

@solidjs/start/server re-exports h3's sendRedirect (which vinxi wraps) which you can use in middleware.

Example

I don't see how sendRedirect is used in your code sample.

if (!sessionId) {
  event.locals.user = null;
  event.locals.session = null;
  // this is where I would expect… 
  return sendRedirect(event, loginHref);
}

That said you have to let the request for loginHref (and any requests supporting that page) pass otherwise you will get into an infinite loop of redirects.

GitHub

SolidStart seed project with simple user management for demonstration projects. - peerreynders/solid-start-demo-login

slow leaf