@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
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β
This example uses github, 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, it is recommended to create 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. To fix this, a Solid-Start middleware is used:
// 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 a protected route can be created:
// 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
>
Accountβ
Usually contains information about the provider being used
and also extends TokenSet
, which is different tokens returned by OAuth Providers.
Extendsβ
Partial
<OpenIDTokenEndpointResponse
>
Propertiesβ
providerβ
provider: string;
Provider's id for this account. Eg.: "google"
providerAccountIdβ
providerAccountId: string;
This value depends on the type of the provider being used to create the account.
- oauth/oidc: The OAuth account's id, returned from the
profile()
callback. - email: The user's email address.
- credentials:
id
returned from theauthorize()
callback
typeβ
type: ProviderType;
Provider's type for this account
expires_atβ
expires_at?: number;
Calculated value based on [OAuth2TokenEndpointResponse.expires_in]([object Object]).
It is the absolute timestamp (in seconds) when the [OAuth2TokenEndpointResponse.access_token]([object Object]) expires.
This value can be used for implementing token rotation together with [OAuth2TokenEndpointResponse.refresh_token]([object Object]).
Seeβ
- https://authjs.dev/guides/basics/refresh-token-rotation#database-strategy
- https://www.rfc-editor.org/rfc/rfc6749#section-5.1
userIdβ
userId?: string;
id of the user this account belongs to
Seeβ
https://authjs.dev/reference/core/adapters#user
Profileβ
The user info returned from your OAuth provider.
Seeβ
https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims
Sessionβ
The active session of the logged in user.
Extendsβ
DefaultSession
Userβ
The shape of the returned object in the OAuth providers' profile
callback,
available in the jwt
and session
callbacks,
or the second parameter of the session
callback, when using a database.
AuthErrorβ
Base error class for all Auth.js errors.
It's optimized to be printed in the server logs in a nicely formatted way
via the logger.error
option.
Extendsβ
Error
Propertiesβ
typeβ
type: ErrorType;
The error type. Used to identify the error in the logs.
CredentialsSigninβ
Can be thrown from the authorize
callback of the Credentials provider.
When an error occurs during the authorize
callback, two things can happen:
- The user is redirected to the signin page, with
error=CredentialsSignin&code=credentials
in the URL.code
is configurable. - If you throw this error in a framework that handles form actions server-side, this error is thrown, instead of redirecting the user, so you'll need to handle.
Extendsβ
SignInError
Propertiesβ
codeβ
code: string;
The error code that is set in the code
query parameter of the redirect URL.
β NOTE: This property is going to be included in the URL, so make sure it does not hint at sensitive errors.
The full error is always logged on the server, if you need to debug.
Generally, we don't recommend hinting specifically if the user had either a wrong username or password specifically, try rather something like "Invalid credentials".
typeβ
type: ErrorType;
The error type. Used to identify the error in the logs.
Inherited fromβ
SignInError.type