1
Fork 0
blog-go-postgres/extras/auth-clerk/README.md
Leonardo Devai 0f051e5c19 Review and modernize all 42 projects to the updated standard
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
2026-09-27 21:10:38 +02:00

46 lines
2.1 KiB
Markdown

# Clerk auth (drop-in)
Replaces the template's local email/password auth with [Clerk](https://clerk.com)
session tokens. Users sign up and sign in through Clerk (hosted pages or one of
its frontend SDKs); this API only verifies the session JWT Clerk issues.
`clerk.go` validates `Authorization: Bearer <token>` against your Clerk
instance's JWKS endpoint (RS256 signature, issuer, expiry, `azp`) and exposes
the Clerk user id via `userID(r)` — the same helper the local setup provides, so the post handlers keep working.
## Swap steps
1. Copy `clerk.go` into the project root and change `package clerkauth` to
`package main`.
2. Delete `auth.go` — register, login, and HS256 tokens are Clerk's job now.
3. In `main.go`, drop the `AUTH_SECRET` lookup (and the `secret` field on
`app`), drop the `/auth/register` and `/auth/login` routes, and wrap the
protected routes with the Clerk middleware:
```go
requireAuth := newClerkAuth()
mux.HandleFunc("POST /posts", requireAuth(a.createPost))
mux.HandleFunc("PUT /posts/{id}", requireAuth(a.updatePost))
mux.HandleFunc("DELETE /posts/{id}", requireAuth(a.deletePost))
```
4. Author ids are now Clerk user ids (strings like `user_2f...`), not integers:
- in `schema.sql`, drop the `users` table and change `posts.author_id` to
`TEXT NOT NULL` (no foreign key) — then reset the database
(`docker compose down`, delete `./data`) so the new schema applies;
- in `posts.go`, change the `post.AuthorID` field to `string` and use
`userID(r)` directly instead of `strconv.ParseInt(userID(r), 10, 64)`.
5. Environment: remove `AUTH_SECRET`, add your instance's issuer and the
origins allowed to mint tokens for this API (checked against the `azp`
claim; leave it unset to skip the check):
```
CLERK_ISSUER=https://your-app.clerk.accounts.dev
CLERK_AUTHORIZED_PARTIES=https://your-site.com,http://localhost:5173
```
The issuer is your Frontend API URL (Clerk dashboard → API keys);
production instances use your own domain, e.g. `https://clerk.your-site.com`.
After the swap `go vet ./...` should pass and every `(auth)` route expects a
Clerk session JWT.