Prompt
How do I protect API endpoints with user authentication?
Latest observation
Oct 6, 2026
OpenAI APIWeb search: off
To protect API endpoints with user authentication, the usual pattern is:
- User logs in
- Server verifies credentials
- Server issues an authentication token or session
- Client sends that token/session with each request
- API checks authentication before allowing access
Common approaches
1) Session-based auth
- After login, the server creates a session and stores it server-side.
- The browser gets a session cookie.
- On each request, the cookie is sent automatically.
Good for: traditional web apps
Pros: simple, secure with proper cookie settings
Cons: less convenient for mobile/SPAs unless carefully handled
2) Token-based auth
- After login, the server returns a JWT or opaque token.
- The client sends it in the
Authorizationheader:
Authorization: Bearer <token>
Good for: APIs, mobile apps, SPAs
Pros: stateless, scalable
Cons: token storage and revocation need careful design
Basic implementation steps
A. Authenticate users at login
- Hash passwords securely with bcrypt, Argon2, or similar.
- Never store plain-text passwords.
B. Issue a token/session
For token-based auth:
- Create a signed token containing user identity and expiry.
- Keep expiry short and use refresh tokens if needed.
C. Protect routes with middleware
Before allowing access to a route:
- Read the session cookie or bearer token
- Validate it
- Load the user
- Reject with
401 Unauthorizedif invalid or missing
D. Authorize actions
Authentication proves who the user is; authorization controls what they can do.
- For example: user vs admin roles, ownership checks, scopes/permissions.
Example: middleware flow
function authMiddleware(req, res, next) {
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith("Bearer ")) {
return res.status(401).json({ error: "Unauthorized" });
}
const token = authHeader.substring(7);
try {
const user = verifyToken(token); // validate signature + expiry
req.user = user;
next();
} catch (err) {
return res.status(401).json({ error: "Invalid or expired token" });
}
}
Then apply it to protected routes:
app.get("/api/profile", authMiddleware, (req, res) => {
res.json({ user: req.user });
});
Security best practices
- Use HTTPS always
- Store passwords with strong hashing
- Set token expiration
- Use refresh tokens if needed
- Protect against CSRF if using cookies
- Set cookies as:
HttpOnlySecureSameSite=LaxorStrict
- Validate input and sanitize data
- Use rate limiting on login endpoints
- Log failed auth attempts
- Don’t put sensitive data in JWT payloads
Choosing between sessions and tokens
- Use sessions if your app is browser-first and server-rendered
- Use tokens if you’re building an API for multiple clients or a SPA/mobile app
If you want, I can show you how to do this in a specific framework like Express, FastAPI, Django, Spring Boot, or ASP.NET.