A secure, lightweight Go web API with JWT authentication and CSRF protection
CSRFence is a production-ready Go web API that implements robust security patterns for modern web applications. It combines JWT-based stateless authentication with CSRF token validation to provide comprehensive protection against common web vulnerabilities.
- JWT Authentication: Stateless authentication using RSA-signed JSON Web Tokens
- ️ CSRF Protection: Cross-Site Request Forgery prevention with token validation
- ️ Modular Architecture: Clean separation of concerns with middleware patterns
- Secure Password Handling: BCrypt hashing for password storage
- Role-Based Access: User role management for authorization
- High Performance: Built with Go's Fiber framework for speed
- Template System: Server-side rendering with Go templates
- Refresh Tokens: Secure token refresh mechanism
csrfence/
├── main.go # Application entry point
├── db/ # Database layer
│ ├── db.go # Database operations
│ └── models/ # Data models
├── server/ # HTTP server
│ ├── server.go # Server configuration
│ ├── middleware/ # HTTP middleware
│ └── templates/ # Template rendering
├── keys/ # RSA key pairs
└── randomstrings/ # Utility functions
- Go 1.22.2 or higher
- OpenSSL (for RSA key generation)
-
Clone the repository
git clone https://github.com/kunalsinghdadhwal/csrfence cd csrfence
-
Install dependencies
go mod download
-
Generate RSA key pairs
The application requires RSA keys for JWT token signing:
# Create keys directory if it doesn't exist mkdir -p keys # Generate private key (4096-bit RSA) openssl genpkey -algorithm RSA -out keys/app.rsa.pem -pkeyopt rsa_keygen_bits:4096 # Extract public key openssl rsa -pubout -in keys/app.rsa.pem -out keys/app.rsa_pub.pem
-
Build and run
go build -o csrfence . ./csrfence
The server will start on localhost:42069
by default.
You can customize the server configuration by modifying the variables in main.go
:
var host = "localhost" // Server host
var port = "42069" // Server port
The application uses RSA key pairs for JWT signing. Keys should be placed in the keys/
directory:
keys/app.rsa.pem
- Private key (keep secure!)keys/app.rsa_pub.pem
- Public key
Authenticate user and receive JWT tokens.
Request Body:
{
"username": "your_username",
"password": "your_password"
}
Response:
{
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"refresh_token": "eyJhbGciOiJSUzI1NiIs...",
"csrf_token": "random_csrf_token_here"
}
Create a new user account.
Request Body:
{
"username": "new_username",
"password": "secure_password",
"role": "user"
}
Access protected resources (requires valid JWT and CSRF token).
Headers:
Authorization: Bearer <jwt_token>
X-CSRF-Token: <csrf_token>
- Algorithm: RSA256 for enhanced security
- Claims: Custom claims including user role and CSRF token
- Expiration: Configurable token lifetime
- Refresh: Secure token refresh mechanism
- Token Generation: Cryptographically secure random tokens
- Validation: Server-side token validation
- Header-based: CSRF tokens passed via HTTP headers
- SameSite Cookies: Additional protection layer
- Hashing: BCrypt with configurable cost
- Salt: Automatic salt generation
- Storage: Never store plaintext passwords
- In-memory user storage (easily replaceable with persistent DB)
- Password hashing and validation
- User CRUD operations
- Refresh token management
- JWT token validation
- CSRF protection
- Request logging and security headers
- Route-specific middleware chains
- Server-side rendering
- Login/Register forms
- Protected page templates
- Template inheritance support
go test ./...
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out
# Build optimized binary
go build -ldflags="-w -s" -o csrfence .
# Or build for different platforms
GOOS=linux GOARCH=amd64 go build -o csrfence-linux .