Skip to content

emekastack/authentication

Repository files navigation

Authentication System with Gin

A robust authentication system built with Go using the Gin web framework, featuring JWT-based authentication, bcrypt password hashing, and PostgreSQL database.

Features

  • ✅ User registration with email validation
  • ✅ User login with JWT tokens
  • ✅ Access tokens (15 minutes expiry)
  • ✅ Refresh tokens (7 days expiry)
  • ✅ Password hashing with bcrypt
  • ✅ Protected routes with middleware
  • ✅ Clean architecture (handlers, services, repositories)
  • ✅ CORS support
  • ✅ Environment-based configuration

Project Structure

authentication/
├── config/              # Configuration loader
├── database/            # Database connection and migrations
├── dto/                 # Data Transfer Objects
├── handlers/            # HTTP handlers
├── middleware/          # Middleware (auth, CORS)
├── models/              # Data models
├── repository/          # Data access layer
├── services/            # Business logic
├── utils/               # Utility functions
├── main.go              # Application entry point
├── .env                 # Environment variables
└── go.mod               # Go module file

Prerequisites

  • Go 1.21 or higher
  • PostgreSQL 12 or higher

Setup Instructions

1. Clone and Navigate

cd /home/emeka/Desktop/builds/learn-go/authentication

2. Set Up Environment Variables

Copy the example environment file and update with your credentials:

cp .env.example .env

Edit .env and update the following values:

  • DB_PASSWORD: Your PostgreSQL password
  • JWT_ACCESS_SECRET: Generate a strong random secret
  • JWT_REFRESH_SECRET: Generate a different strong random secret

Important: Use strong, unique secrets in production!

3. Create Database

# Connect to PostgreSQL
psql -U postgres

# Create the database
CREATE DATABASE auth_db;

# Exit psql
\q

4. Run Database Migrations

psql -U postgres -d auth_db -f database/migrations.sql

5. Install Dependencies

go mod tidy

6. Run the Application

go run main.go

The server will start on http://localhost:8080

API Endpoints

Public Endpoints

Register User

POST /api/auth/register
Content-Type: application/json

{
  "email": "user@example.com",
  "password": "SecurePassword123!",
  "name": "John Doe"
}

Response:

{
  "user": {
    "id": "uuid",
    "email": "user@example.com",
    "name": "John Doe",
    "created_at": "timestamp"
  },
  "access_token": "jwt_token",
  "refresh_token": "jwt_token"
}

Login

POST /api/auth/login
Content-Type: application/json

{
  "email": "user@example.com",
  "password": "SecurePassword123!"
}

Response: Same as registration

Refresh Token

POST /api/auth/refresh
Content-Type: application/json

{
  "refresh_token": "your_refresh_token"
}

Response:

{
  "access_token": "new_jwt_token"
}

Protected Endpoints

Get Current User

GET /api/auth/me
Authorization: Bearer <access_token>

Response:

{
  "id": "uuid",
  "email": "user@example.com",
  "name": "John Doe",
  "created_at": "timestamp"
}

Health Check

GET /health

Testing with cURL

1. Register a new user

curl -X POST http://localhost:8080/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "test@example.com",
    "password": "SecurePass123!",
    "name": "Test User"
  }'

2. Login

curl -X POST http://localhost:8080/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "test@example.com",
    "password": "SecurePass123!"
  }'

3. Access protected endpoint (replace TOKEN with your access token)

curl -X GET http://localhost:8080/api/auth/me \
  -H "Authorization: Bearer TOKEN"

4. Refresh access token (replace REFRESH_TOKEN)

curl -X POST http://localhost:8080/api/auth/refresh \
  -H "Content-Type: application/json" \
  -d '{
    "refresh_token": "REFRESH_TOKEN"
  }'

Security Features

  • Password Hashing: Bcrypt with default cost (10)
  • JWT Tokens: HMAC-SHA256 signing
  • Token Expiry: Short-lived access tokens, longer refresh tokens
  • Input Validation: Email format, password minimum length (8 chars)
  • SQL Injection Protection: Parameterized queries
  • CORS: Configurable cross-origin support

Environment Variables

Variable Description Default
SERVER_PORT HTTP server port 8080
DB_HOST PostgreSQL host localhost
DB_PORT PostgreSQL port 5432
DB_USER Database user postgres
DB_PASSWORD Database password postgres
DB_NAME Database name auth_db
DB_SSLMODE SSL mode disable
JWT_ACCESS_SECRET Access token secret Required
JWT_REFRESH_SECRET Refresh token secret Required
JWT_ACCESS_EXPIRY Access token expiry 15m
JWT_REFRESH_EXPIRY Refresh token expiry 168h
APP_ENV Environment development

Error Responses

All errors follow this format:

{
  "error": "error_code",
  "message": "Human-readable error message"
}

Common error codes:

  • bad_request (400): Invalid input
  • unauthorized (401): Invalid or missing token
  • not_found (404): Resource not found
  • internal_error (500): Server error

Production Considerations

  1. Generate Strong Secrets: Use cryptographically secure random strings for JWT secrets
  2. Database SSL: Enable SSL for database connections in production
  3. HTTPS: Always use HTTPS in production
  4. Rate Limiting: Add rate limiting middleware to prevent abuse
  5. Logging: Implement proper logging for security events
  6. Token Blacklisting: Consider implementing token blacklisting for logout
  7. Password Requirements: Enforce stronger password policies

License

MIT

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published