OAuth & Providers
Configure providers
Section titled “Configure providers”import { createAuth, google, github, credentials } from "@mountsqli/auth";
const auth = createAuth({ db, secret: process.env.JWT_SECRET!, providers: [ google({ clientId: "...", clientSecret: "..." }), github({ clientId: "...", clientSecret: "..." }), credentials({ authorize: async ({ email, password }) => { const user = await lookupUser(email); if (!user || !verifyPassword(user.password, password)) return null; return { id: user.id, email: user.email }; }, }), ],});| Provider | Import | Config |
|---|---|---|
google |
{ clientId, clientSecret, scope? } |
|
| GitHub | github |
{ clientId, clientSecret, scope? } |
| Password | credentials |
{ authorize: (creds) => User | null } |
OAuth flow
Section titled “OAuth flow”// Step 1 — redirect the user to the providerconst url = await auth.signIn("google");// redirect user to urlSets identifier: state:<random> in authVerificationTokens for CSRF
protection (expires 10 minutes).
// Step 2 — handle the callbackconst result = await auth.handleCallback("google", { code: req.query.code, state: req.query.state,});// { user, session, token } | throws ProviderErrorThe callback validates the state (CSRF), exchanges the code for tokens,
fetches user info, and creates or links an account in authAccounts.
Callbacks
Section titled “Callbacks”The Auth config supports lifecycle callbacks:
createAuth({ db, secret, providers: [/* ... */], callbacks: { onRegister: async (user) => { /* welcome email */ }, onLogin: async (user) => { /* audit log */ }, onLogout: async (session) => { /* cleanup */ }, onSession: async (session) => { /* enrich session data */ }, },});Credentials provider
Section titled “Credentials provider”The credentials provider lets you authenticate with email + password. Your
authorize function receives the form data and returns a User or null.
credentials({ authorize: async ({ email, password }) => { const user = await db.query(authUsers).where("email", "=", email).findOne(); if (!user?.password) return null; if (!verifyPassword(password, user.password)) return null; return { id: user.id, email: user.email }; },});Best practices
Section titled “Best practices”- Scope OAuth providers to the minimum
scopeyour app needs. - Use
credentialsfor email/password; use OAuth providers for social login. - Validate email is verified on the OAuth provider before creating the user.
Common mistakes
Section titled “Common mistakes”- Expecting
handleCallbackto accept a response object (it receives params, notres). - Forgetting to pass
providersin the config —auth.signInthrowsProviderError.
Related
Section titled “Related”- Sessions — what
handleCallbackreturns. - Passwords & JWT — how tokens work.
