Pinned 2026 toolchains (Go 1.26, Rust 1.98/edition 2024, Python 3.14 + uv, Node 24, Zig 0.16, NixOS 26.05), postgres 18 / mongo 8, lockfiles built from, non-root runtimes, .dockerignore, per-project LICENSE, READMEs with the git.devai.io clone line, checkout@v7 CI. Security fixes in the legacy Rust APIs (any-password login, self-assigned admin, hard-coded JWT secret), JWT alg/exp/sub enforcement across the blog series, safe markdown links in the frontends, and many smaller bugs — every project was built, run and exercised end to end. Adds scripts/publish.sh + a CI publish job that splits every folder into its own repo at git.devai.io/templates/<folder>. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01128fhuZbgivaSJvtMf4s1G
1.9 KiB
Auth via Auth0
Replaces the local email+password auth with Auth0. The app stops issuing tokens itself and instead verifies Auth0-issued access tokens (RS256) against your tenant's JWKS, checking issuer and audience.
Setup
-
In the Auth0 dashboard create an API (Applications → APIs). Its identifier is your audience. Your tenant domain (e.g.
your-tenant.us.auth0.com) is the issuer host. -
Add the HTTP client to
Cargo.toml:reqwest = { version = "0.13", features = ["json"] } -
Copy
auth0.rstosrc/auth0.rsand deletesrc/auth.rs— Auth0 hosts sign-up and sign-in. Insrc/main.rs, replacemod auth;withmod auth0;, then remove the/auth/registerand/auth/loginroutes, the unusedpostimport, and thejwt_secretstate field along with itsAUTH_SECRETline. -
In
src/posts.rs:- import the new extractor:
use crate::auth0::AuthUser; - Auth0 user ids are strings (
auth0|...), not ObjectIds: changeauthor_id: ObjectIdinPosttoauthor_id: String, theuser_id: ObjectIdparameter offind_own_posttouser_id: String, andpost.author_id.to_hex()inpost_jsontopost.author_id.
- import the new extractor:
-
Auth0 is the user store now: in
src/db.rs, remove theusersfield, itsemailindex and theUserimport. -
Set the environment variables:
AUTH0_DOMAIN=your-tenant.us.auth0.com AUTH0_AUDIENCE=https://api.example.com
Notes
- Clients obtain access tokens through one of Auth0's flows (Authorization
Code + PKCE for SPAs; Client Credentials for a quick server-side test) and
send them as
Authorization: Bearer <token>. Request the token with your API's audience, or it is rejected. - The JWKS is fetched on first use and cached. A token signed with an unknown key id triggers a refetch (at most once a minute), so key rotations need no restart.