GoGateway API

Index
Prerequisites
Setup
Clone the Repository
git clone https://github.com/zvdy/gogateway-api.git
cd gogateway-api
Create Configuration File
Create a config.yaml file in the root directory with the following content:
ServerAddress: ":8080"
RedisAddress: "redis:6379"
RedisPassword: ""
RedisDB: 0
Build and Run the Docker Containers
Use Docker Compose to build and run the containers:
docker-compose up --build
Test the router
# client
curl http://localhost:8080/health
{"status":"healthy"}
#server
api-gateway | [GIN] 2024/11/24 - 19:18:49 | 200 | 151.849µs | 172.27.0.1 | GET "/health"
Generate a JWT Token
Create a gen_token.go file in the root directory with the following content:
[!WARNING]
If you modify the claims, the script will have to be modified too.
package main
import (
"fmt"
"log"
"github.com/zvdy/gogateway-api/internal/auth"
)
func main() {
token, err := auth.GenerateJWT("test-user-id")
if err != nil {
log.Fatalf("Failed to generate JWT: %v", err)
}
fmt.Println("Generated JWT:", token)
}
Run the script to generate a JWT token:
go run gen_token.go
Generated JWT: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzI1NjE5NTksInVzZXJfaWQiOiJ0ZXN0LXVzZXItaWQifQ.79bjRnzgN7ub1757ecWOj0-cx4uo0dnjGU1ZLCPGfaQ
JWT Auth in Depth
internal/auth/auth.go contains the logic to generate the tokens. at the moment.
The key is hardcoded, and as a personal recommendation, I suggest using openssl rand -base64 32.
var secretKey = []byte("vyPcARcpHaov7o7aU1kDcLHjR0ZR9+UWx/TqtCvhl+g=") // ❯ openssl rand -base64 32
You can also modify the claims rfc7519.
func GenerateJWT(userID string) (string, error) {
claims := jwt.MapClaims{
"user_id": userID,
"exp": time.Now().Add(24 * time.Hour).Unix(),
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString(secretKey)
}
I suggest using this web To verify jwt signatures and general work with JWT.
Use the JWT Token to Authenticate
Replace <JWT_TOKEN> with the token generated in the previous step and use it to authenticate and access the API Gateway:
# client
export TOKEN='<JWT_TOKEN>'
curl -H "Authorization: Bearer $TOKEN" http://localhost:8080/api/test
Hello from backend
# server
api-gateway | [GIN] 2024/11/24 - 19:17:20 | 200 | 684.511µs | 172.27.0.1 | GET "/api/test"
Test the Rate Limiting
Create a loadtest.sh file in the root directory with the following content:
#!/bin/bash
TOKEN='<JWT_TOKEN>'
URL='http://localhost:8080/api/test'
for i in {1..110}; do
echo "Request $i"
curl -H "Authorization: Bearer $TOKEN" $URL
echo
done
Run the script to test the rate limiting:
chmod +x loadtest.sh
./loadtest.sh
...
...
...
Request 101
{"error":"rate limit exceeded"}
Project Structure
.
├── cmd
│ └── main.go
├── config.yaml
├── Dockerfile
├── Dockerfile.backend
├── docker-compose.yml
├── go.mod
├── go.sum
├── internal
│ ├── auth
│ │ └── auth.go
│ ├── cache
│ │ ├── cache.go
│ │ └── middleware.go
│ ├── logging
│ │ └── logger.go
│ ├── proxy
│ │ └── proxy.go
│ ├── ratelimit
│ │ ├── middleware.go
│ │ └── ratelimiter.go
│ └── routes
│ ├── handlers.go
│ └── router.go
├── pkg
│ ├── middleware
│ │ ├── cors.go
│ │ └── recovery.go
│ └── utils
│ ├── http.go
│ └── json.go
├── backend
│ └── backend.go
├── gen_token.go
├── loadtest.sh
├── README.md
└── test
└── integration
├── auth_test.go
License
This project is licensed under the MIT License.