Authentication API
All routes in this module are mounted under /api/auth. They are mostly public except where noted; protected user routes live under /api/user and use JWT middleware instead.
Endpoint catalogue
Register
POST /api/auth/register
Creates a new user with a hashed password. Typical body fields include name, email, telephone, and password — see modules/user/dto for exact JSON keys and validation tags.
Errors you might return include duplicate email, validation failures, or database constraint violations — map them to consistent HTTP status codes in the controller.
Login
POST /api/auth/login
Validates email/password, then returns:
access_token— JWT, short lived.refresh_token— opaque string stored server-side with expiry.role— string role from the user row (starter often defaults new users touser).
Refresh
POST /api/auth/refresh
Body includes the current refresh token. The service:
- Looks up the refresh row (with preloaded user).
- Deletes the old refresh token row (rotation).
- Inserts a new refresh token with a new random value and expiry.
- Returns fresh access and refresh tokens.
If the token is unknown, respond with 401 — clients should then redirect to login.
Logout
POST /api/auth/logout
Expects user_id on the Gin context (set by JWT middleware in real flows) and deletes refresh token rows for that user. If you call this route without middleware in tests, you must mimic context keys.
Email verification
Two-step flow:
POST /api/auth/send-verification-email— looks up user, ensures not already verified, sends mail with embedded token (implementation uses JWT as a simple carrier in the template — review before production).POST /api/auth/verify-email— validates token, marks user verified.
Password reset
POST /api/auth/send-password-reset— sends mail with reset token.POST /api/auth/reset-password— validates token, sets new password hash.
Token design
Access token (JWT)
- Signed with
JWT_SECRET. - Carries claims such as
user_idandrole. - Validated by
middlewares.Authenticateusing the sharedjwt.JWTService.
Refresh token
- Opaque random string — not a JWT.
- Stored in
refresh_tokenstable with expiry and foreign key tousers. - Rotation on refresh reduces replay window if a refresh leaks.
Middleware integration
Protected routes use:
middlewares.Authenticate(jwtService)
The JWT service instance is resolved from the same DI graph as controllers. After success, handlers read:
userId := ctx.MustGet("user_id").(string)
Keep key names consistent across modules.
Security notes (production)
- Prefer HTTPS everywhere — tokens in headers are still sensitive on plaintext HTTP.
- Consider refresh token families or device binding for high-risk apps.
- Rate-limit login and reset endpoints to mitigate brute force and email spam.
Extending auth
| Goal | Suggestion |
|---|---|
| OAuth2 / social login | Add new routes + services; persist provider IDs on users. |
| Step-up MFA | Issue short-lived scopes; add challenge endpoint. |
| Session list UI | Query refresh_tokens by user with metadata columns you add. |
The existing layering (controller → service → repository) keeps those changes localized.