diff --git a/website/app/docs/auth/page.ts b/website/app/docs/auth/page.ts index 4042fb6e3..dcc59d6ed 100644 --- a/website/app/docs/auth/page.ts +++ b/website/app/docs/auth/page.ts @@ -1,11 +1,16 @@ import { html } from '@webjsdev/core'; -export const metadata = { title: 'Authentication | WebJs' }; +export const metadata = { + title: 'Auth Providers (createAuth) | WebJs', + description: + 'The built-in createAuth() surface: OAuth providers, credentials login, and JWT sessions with no external auth library. Covers setup, the auth API route, reading the session, callbacks, and session strategies.', +}; export default function Auth() { return html` -
WebJs provides NextAuth-style authentication with OAuth providers, credentials login, and JWT sessions. No external auth library needed.
+WebJs ships createAuth(), a NextAuth-style auth surface with OAuth providers, credentials login, and JWT sessions. Reach for this page when you want providers and sessions handled for you, and no external auth library in the dependency tree.
It is not the only route. If you want to own the session format, the password hashing, and the route-protection rules yourself, build on the framework primitives instead, which is what Build your own authentication covers and what the blog example does. Pick createAuth() for OAuth and a batteries-included setup, pick the primitives when you want full control of the session.
// lib/auth.server.ts: create once
diff --git a/website/app/docs/authentication/page.ts b/website/app/docs/authentication/page.ts
index f4bd618e3..171e3d72f 100644
--- a/website/app/docs/authentication/page.ts
+++ b/website/app/docs/authentication/page.ts
@@ -1,11 +1,16 @@
import { html } from '@webjsdev/core';
-export const metadata = { title: 'Authentication | WebJs' };
+export const metadata = {
+ title: 'Build Your Own Authentication | WebJs',
+ description:
+ 'Build session-based authentication on the WebJs primitives when you want to own the session format, scrypt password hashing, and middleware route protection, instead of using the built-in createAuth() providers.',
+};
export default function Authentication() {
return html`
- Authentication
- WebJs doesn't ship an auth library. It provides the primitives you need to build session-based authentication cleanly. The blog example demonstrates a complete implementation using scrypt password hashing, session tokens in cookies, and middleware-based route protection.
+ Build your own authentication
+ This page is the hand-rolled route: session-based auth built on the framework primitives, where you own the session format, the password hashing, and the route-protection rules. The blog example is a complete implementation of it, using scrypt password hashing, session tokens in cookies, and middleware-based route protection.
+ WebJs does ship a batteries-included option, so this is a choice rather than a necessity. Auth providers (createAuth) gives you OAuth providers, credentials login, and JWT sessions out of the box. Take that page if you want OAuth or do not want to own the session. Stay here if you want full control over how a session is minted, stored, and checked.
Architecture
lib/
diff --git a/website/app/docs/cache/page.ts b/website/app/docs/cache/page.ts
index 6c215be51..199d0ebcc 100644
--- a/website/app/docs/cache/page.ts
+++ b/website/app/docs/cache/page.ts
@@ -195,7 +195,7 @@ setStore(redisStore({ url: process.env.REDIS_URL }));
Next Steps
Cross-origin vendor modules (resolved from jspm.io) carry a standard SRI integrity hash so a swapped or compromised CDN response cannot execute unverified. This now applies on both paths: a pinned app (webjs vendor pin) ships the hashes in its committed importmap, and an un-pinned app computes them live at warmup. SRI computation is fail-open: a CDN fetch failure during the live path skips that one hash with a warning rather than taking the app down. For reproducible hashes and zero warmup fetches, pin. See No-Build Model.
Session cookies are signed, so set a strong AUTH_SECRET (and SESSION_SECRET where used), 32 or more random characters, in production. Keep all secrets server-only: any process.env name WITHOUT the WEBJS_PUBLIC_ prefix never reaches the browser (reading process.env.DATABASE_URL from a component returns undefined, the same as a typo). The prefix is fail-closed, so a secret cannot leak by accident. Prefer your platform's secret injection over a committed .env file. See Sessions and Auth.
Session cookies are signed, so set a strong AUTH_SECRET (and SESSION_SECRET where used), 32 or more random characters, in production. Keep all secrets server-only: any process.env name WITHOUT the WEBJS_PUBLIC_ prefix never reaches the browser (reading process.env.DATABASE_URL from a component returns undefined, the same as a typo). The prefix is fail-closed, so a secret cannot leak by accident. Prefer your platform's secret injection over a committed .env file. See Sessions and Auth providers (createAuth).
Protect auth endpoints and other abuse-prone routes with the rateLimit({ window, max }) middleware, placed at any route level (it applies to that subtree). Behind a reverse proxy or CDN, set trustProxy: true so it keys on the forwarded client IP, and make sure the proxy strips an inbound X-Forwarded-For before adding its own. See Rate Limiting.
const { auth } = createAuth<AppUser>({ secret, providers });
const session = await auth();
session?.user.role; // typed, no cast
- Un-augmented and un-parameterised, AuthUser is empty and resolves back to Record<string, unknown>, so pre-existing untyped code keeps compiling. The declared fields should mirror what the callbacks write onto session.user. See Auth.
Un-augmented and un-parameterised, AuthUser is empty and resolves back to Record<string, unknown>, so pre-existing untyped code keeps compiling. The declared fields should mirror what the callbacks write onto session.user. See Auth providers (createAuth).
If you prefer .js files, you can achieve the same type safety using JSDoc annotations with checkJs: true in your tsconfig: