This is a robust and scalable authentication microservice built with Go, following clean architecture principles. It provides user registration, login, token refreshing, and user management functionalities, using JWT for secure authentication and Redis for token management/blacklisting.
- User Authentication: Secure Login and Registration using bcrypt for password hashing.
- JWT Management: Issues Access and Refresh tokens.
- Token Revocation: Logout functionality that blacklists tokens in Redis.
- User Management: Full CRUD operations for user profiles (protected by auth middleware).
- Clean Architecture: Separation of concerns into domain, infrastructure, and application layers.
- Containerized: Fully Dockerized for easy deployment and local development.
- Database Migrations & Seeding: Built-in tools for managing database schema and initial data.
- Testing Suite: Includes both unit and integration tests using Testcontainers.
- Language: Go 1.25+
- Web Framework: Gin Gonic
- ORM: GORM (supports MySQL, PostgreSQL, SQLite)
- Cache: Redis
- Authentication: JWT (golang-jwt)
- Migrations: golang-migrate
- Testing: Testify & Testcontainers
- Docker and Docker Compose.
- Go (optional, for local development outside Docker).
make(utility to run Makefile commands).
-
Clone the repository:
git clone <repository-url> cd auth
-
Initialize the project: This command will copy the
.env.example, start the Docker containers, run migrations, and execute tests.make init
-
Run the application (Development mode):
make run-dev
The project includes a Makefile to simplify common tasks:
| Command | Description |
|---|---|
make up |
Start infrastructure (MySQL, Redis, etc.) in background. |
make down |
Stop all containers. |
make migrate |
Run database migrations. |
make migrate-fresh |
Drop all tables and rerun migrations. |
make seed |
Populate the database with dummy data. |
make test |
Run all integration and unit tests. |
make run-prod |
Build and run the service in production-like mode. |
POST /register: Register a new user.POST /login: Authenticate and receive JWT tokens.POST /refresh: Get a new access token using a refresh token.DELETE /logout: Revoke current tokens.
GET /: List all users.POST /: Create a user manually.GET /:uuid: Get user details by UUID.PATCH /:uuid: Update user information.DELETE /:uuid: Remove a user.
├── cmd/ # Entry points (API, Migrations, Seeder)
├── internal/
│ ├── bootstrap/ # App initialization logic
│ ├── domain/ # Business logic (Auth, User modules)
│ │ └── auth/ # Auth actions, handlers, services
│ │ └── user/ # User entity, repository, handlers
│ ├── infrastructure/ # Frameworks & Drivers (DB, Redis, Config, Middlewares)
├── tests/ # Integration and Unit tests
├── Dockerfile # Production build configuration
└── docker-compose.yaml # Local development environment
Key configurations found in .env:
APP_PORT: Server port (default: 8080).DB_DRIVER:mysql,postgres, orsqlite.AUTH_JWT_SECRET: Secret key for signing tokens.AUTH_ACCESS_TOKEN_EXPIRE: Access token TTL in minutes.REDIS_HOST: Redis connection host.
To publish a new message to Kafka, follow these 3 steps without touching any messaging infrastructure files:
1. Create the DTO in internal/shared/messaging/kafka/dtos/:
// internal/shared/messaging/kafka/dtos/password_reset.go
type PasswordReset struct {
Email string `json:"email"`
Token string `json:"token"`
}2. Register the route in setupPublisher inside internal/bootstrap/api.go:
publisher.Register(dtos.PasswordReset{}, messaging.Route{
RoutingKey: "user.password_reset",
})3. Inject and publish in your domain action. Depend on the actions.MessagePublisher interface and call Publish:
type MyAction struct {
publisher actions.MessagePublisher
// ...
}
func (a *MyAction) Execute(ctx context.Context, ...) error {
return a.publisher.Publish(ctx, dtos.PasswordReset{Email: email, Token: token})
}No infrastructure files need to be modified.
Run tests using Docker to ensure a clean environment (uses Testcontainers for DB/Redis):
make test