BoilerPrompt
Replit Agent

Replit Agent prompt to add JWT authentication

Built-in session auth covers browsers, but external API clients need tokens, which means rotation, revocation, and honest 401 codes. This prompt directs Replit Agent to build the full JWT refresh lifecycle on your Express API and prove it with a curl sequence from the workspace shell. You get an auth layer you can hand to API consumers.

Last updated

Prompt
Add JWT authentication to the Express API in this Repl. Do not swap in Replit Auth, I need token auth for external API clients.

Endpoints: POST /api/auth/register with email and password. POST /api/auth/login returning a short-lived access token in the JSON body and a refresh token in an httpOnly secure cookie. POST /api/auth/refresh that rotates the refresh token. POST /api/auth/logout that revokes it.

Storage: a users table holding a bcrypt hash, never the raw password. A refresh_tokens table with token hash, user_id, expires_at, and revoked_at so rotation and logout are enforceable server-side. Use the built-in Postgres database.

Secrets: read the signing key from Replit Secrets, generating and storing one if missing. Fail loudly at startup if it is absent in production.

Middleware: requireAuth verifies the access token, attaches the user id to the request, and returns 401 with a machine-readable code of token_expired or token_invalid so clients know whether to refresh or log in again. Protect the routes I list, leave health checks open.

Edge cases: duplicate registration returns 409, a reused rotated refresh token revokes that token's whole family, and clock skew tolerance stays small.

Verify from the workspace shell: a curl sequence covering register, login, an authorized call, an expired-token 401, a refresh, and a post-logout refresh that fails. Paste the commands and outputs, then list every changed file.

Same task in other tools

Questions about this prompt

Why does the refresh token go in a cookie but the access token in the body?

Browser clients get httpOnly protection on the long-lived credential, while the short-lived access token stays available to any client that can read JSON. The split limits what a script injection can steal to a token that expires quickly.

My clients are mobile apps, not browsers, what changes?

Return the refresh token in the response body instead of a cookie and let the app store it in the platform keystore. Rotation, family revocation, and the refresh_tokens table stay exactly as specced.

Every request starts returning 401 after a while, is that a bug?

Check the machine-readable code in the response body first. token_expired means the client never wired the refresh call, which is the common case. token_invalid points at a signing key mismatch, so confirm the key in Secrets was not regenerated.

Related prompts