@auth/solid-start
@auth/solid-start
is currently experimental. The API will change in the future.
SolidStart Auth is the official SolidStart integration for Auth.js. It provides a simple way to add authentication to your SolidStart app in a few lines of code.
Installationβ
- npm
- Yarn
- pnpm
npm install @auth/core @auth/solid-start
yarn add @auth/core @auth/solid-start
pnpm add @auth/core @auth/solid-start
We recommended to using create-jd-app
SolidAuth()β
SolidAuth(config): {
GET: Promise< undefined | Response >;
POST: Promise< undefined | Response >;
}
Setupβ
Generate an auth secret, then set it as an environment variable:
AUTH_SECRET=your_auth_secret
Creating the API handlerβ
in this example we are using github so make sure to set the following environment variables:
GITHUB_ID=your_github_oauth_id
GITHUB_SECRET=your_github_oauth_secret
// routes/api/auth/[...solidauth].ts
import { SolidAuth, type SolidAuthConfig } from "@auth/solid-start"
import GitHub from "@auth/core/providers/github"
export const authOpts: SolidAuthConfig = {
providers: [
GitHub({
clientId: process.env.GITHUB_ID,
clientSecret: process.env.GITHUB_SECRET,
}),
],
debug: false,
}
export const { GET, POST } = SolidAuth(authOpts)
Getting the current sessionβ
import { getSession } from "@auth/solid-start"
import { createServerData$ } from "solid-start/server"
import { authOpts } from "~/routes/api/auth/[...solidauth]"
export const useSession = () => {
return createServerData$(
async (_, { request }) => {
return await getSession(request, authOpts)
},
{ key: () => ["auth_user"] }
)
}
// useSession returns a resource:
const session = useSession()
const loading = session.loading
const user = () => session()?.user
Protected Routesβ
When Using SSRβ
When using SSR, I recommend creating a Protected
component that will trigger suspense using the Show
component. It should look like this:
// components/Protected.tsx
import { type Session } from "@auth/core/types";
import { getSession } from "@auth/solid-start";
import { Component, Show } from "solid-js";
import { useRouteData } from "solid-start";
import { createServerData$, redirect } from "solid-start/server";
import { authOpts } from "~/routes/api/auth/[...solidauth]";
const Protected = (Comp: IProtectedComponent) => {
const routeData = () => {
return createServerData$(
async (_, event) => {
const session = await getSession(event.request, authOpts);
if (!session || !session.user) {
throw redirect("/");
}
return session;
},
{ key: () => ["auth_user"] }
);
};
return {
routeData,
Page: () => {
const session = useRouteData<typeof routeData>();
return (
<Show when={session()} keyed>
{(sess) => <Comp {...sess} />}
</Show>
);
},
};
};
type IProtectedComponent = Component<Session>;
export default Protected;
It can be used like this:
// routes/protected.tsx
import Protected from "~/components/Protected";
export const { routeData, Page } = Protected((session) => {
return (
<main class="flex flex-col gap-2 items-center">
<h1>This is a protected route</h1>
</main>
);
});
export default Page;
When Using CSRβ
When using CSR, the Protected
component will not work as expected and will cause the screen to flash, so I had to come up with a tricky solution, we will use a Solid-Start middleware:
// entry-server.tsx
import { Session } from "@auth/core";
import { getSession } from "@auth/solid-start";
import { redirect } from "solid-start";
import {
StartServer,
createHandler,
renderAsync,
} from "solid-start/entry-server";
import { authOpts } from "./routes/api/auth/[...solidauth]";
const protectedPaths = ["/protected"]; // add any route you wish in here
export default createHandler(
({ forward }) => {
return async (event) => {
if (protectedPaths.includes(new URL(event.request.url).pathname)) {
const session = await getSession(event.request, authOpts);
if (!session) {
return redirect("/");
}
}
return forward(event);
};
},
renderAsync((event) => <StartServer event={event} />)
);
And now you can easily create a protected route:
// routes/protected.tsx
export default () => {
return (
<main class="flex flex-col gap-2 items-center">
<h1>This is a protected route</h1>
</main>
);
};
The CSR method should also work when using SSR, the SSR method shouldn't work when using CSR
Parametersβ
βͺ config: SolidAuthConfig
Returnsβ
object
GET()β
Parametersβ
βͺ event:
any
Returnsβ
Promise
<undefined
|Response
>POST()β
Parametersβ
βͺ event:
any
Returnsβ
Promise
<undefined
|Response
>