Authentication
Import your shared auth instance:
import { simple } from '~/lib/simpleLogin'
Redirect to Login
When a user needs to sign in, redirect them to the hosted login UI:
// app/routes/login.tsx
export async function loader() {
return simple.redirectToAuth()
}
Returns a Response that redirects to a secure login page. The user authenticates using their preferred method.
Handle the Callback
After authentication, the user is redirected to your redirect_uri:
// app/routes/auth.callback.tsx
export async function loader({ request }: { request: Request }) {
const { response, user } = await simple.handleCallback(request, '/home')
// Optional: store user in your database
await db.users.upsert({
id: user.sub,
email: user.email,
name: user.name,
})
return response
}
The response sets secure cookies and redirects to /home.
Verify Requests
Protect your routes with authenticate:
// app/routes/dashboard.tsx
export async function loader({ request }: { request: Request }) {
const session = await simple.authenticate(request)
if (!session) {
return simple.redirectToAuth()
}
const userId = session.claims.sub
// Include session.headers - they may contain refreshed tokens
return new Response(JSON.stringify({ userId }), {
headers: session.headers,
})
}
Returns null if not authenticated. Otherwise returns:
claims- session info (user id, email, etc.)headers- may contain refreshed tokens, include them in your response
Logout
// app/routes/logout.tsx
export async function loader({ request }: { request: Request }) {
return simple.logout(request)
}
Revokes the session, clears cookies, redirects to login.
Quick Reference
| Method | Returns |
|---|---|
redirectToAuth() | Response - redirects to login |
handleCallback(request, redirectTo) | { response, user } - exchanges code, sets cookies |
authenticate(request) | { claims, headers } or null |
logout(request) | Response - clears session, redirects to login |
Full Example
// app/routes/dashboard.tsx
import { simple } from '~/lib/simpleLogin'
export async function loader({ request }: { request: Request }) {
const session = await simple.authenticate(request)
if (!session) {
return simple.redirectToAuth()
}
const data = await getDataForUser(session.claims.sub)
return new Response(JSON.stringify(data), {
headers: session.headers,
})
}
No cookie management, no token handling, automatic session refresh.