Lightweight and Secure OAuth2 for SolidStart - Access the name, email, and when available image of authenticated users.
For extended usage, the oauth object includes the provider name, the provider's stable user id, and the access token. Key accounts on (provider, id) rather than email - every email is provider-verified at sign-in, but addresses can still change over time.
Supported Providers: Discord, GitHub, GitLab, Google, LinkedIn, Slack, Twitch, X, and Yahoo
Add start-oauth as a dependency
# use preferred package manager
npm add start-oauthCreate a catch-all API route at routes/api/oauth/[...oauth].ts
import OAuth from "start-oauth";
import { redirect } from "@solidjs/router";
export const GET = OAuth({
password: process.env.PASSWORD!, // openssl rand -hex 32
discord: {
id: process.env.DISCORD_ID!,
secret: process.env.DISCORD_SECRET!
},
google: {
id: process.env.GOOGLE_ID!,
secret: process.env.GOOGLE_SECRET!
},
async handler({ name, email, image, oauth }, redirectTo) {
// add your logic (e.g. database call, session creation)
// const session = await getSession();
// await session.update({ name, email, image });
return redirect(
// only allow internal redirects
redirectTo?.startsWith("/") && !redirectTo.startsWith("//")
? redirectTo
: "/defaultPage"
);
}
});In your OAuth provider's dashboard, set the redirect URIs
- Development:
http://localhost:3000/api/oauth/[provider] - Production:
https://your-domain.com/api/oauth/[provider]
// for example in routes/login.tsx
import { useOAuthLogin } from "start-oauth";
export default function Login() {
const login = useOAuthLogin();
return (
<div>
<a href={login("discord")} rel="external">
Sign in with Discord
</a>
<a href={login("google")} rel="external">
Sign in with Google
</a>
</div>
);
}- To specify a post-login destination, append
?redirect=/dashboardto the login URL—this value is passed as theredirectToparameter to your handler. - On authentication failure, users are redirected to the login page with
?error=<reason>for custom error handling.
See start-oauth in action with the SolidStart with-auth example
# using npm
npm create solid@latest -- -st with-auth# using pnpm
pnpm create solid@latest -st with-auth# using bun
bun create solid@latest --s --t with-auth- Sign-in requires an email the provider attests as verified
- PKCE with SHA-256 code challenges on every provider that supports it
- AES-256-GCM encryption for state parameters to prevent tampering
- Timeout-protected HTTP requests to avoid hanging connections
- Strict validation of fallback URLs to prevent open redirects