https://github.com/zvdy/api-gateway
Golang API gateway that incorporates Rate Limiting using redis and JWT user authentication.
https://github.com/zvdy/api-gateway
api gateway-api golang jwt-authentication rate-limiting redis
Last synced: 18 days ago
JSON representation
Golang API gateway that incorporates Rate Limiting using redis and JWT user authentication.
- Host: GitHub
- URL: https://github.com/zvdy/api-gateway
- Owner: zvdy
- License: mit
- Created: 2024-11-24T19:24:54.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2024-11-25T12:11:23.000Z (over 1 year ago)
- Last Synced: 2025-07-06T16:24:43.153Z (12 months ago)
- Topics: api, gateway-api, golang, jwt-authentication, rate-limiting, redis
- Language: Go
- Homepage:
- Size: 20.5 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# GoGateway API
[](https://goreportcard.com/report/github.com/zvdy/api-gateway)
# Index
- [Prerequisites](#prerequisites)
- [Setup](#setup)
- [Clone the Repository](#clone-the-repository)
- [Create Configuration File](#create-configuration-file)
- [Build and Run the Docker Containers](#build-and-run-the-docker-containers)
- [Test the router](#test-the-router)
- [Client](#client)
- [Server](#server)
- [Generate a JWT Token](#generate-a-jwt-token)
- [JWT Auth in Depth](#jwt-auth-in-depth)
- [You can also modify the claims](https://datatracker.ietf.org/doc/html/rfc7519#section-4)
- [Use the JWT Token to Authenticate](#use-the-jwt-token-to-authenticate)
- [Client](#client-1)
- [Server](#server-1)
- [Test the Rate Limiting](#test-the-rate-limiting)
- [Project Structure](#project-structure)
- [License](#license)
## Prerequisites
- [Docker](https://docs.docker.com/get-started/get-docker/)
- [Docker Compose](https://docs.docker.com/compose/install/)
- [Go](https://go.dev/doc/install)
## Setup
### Clone the Repository
```sh
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:
```yaml
ServerAddress: ":8080"
RedisAddress: "redis:6379"
RedisPassword: ""
RedisDB: 0
```
### Build and Run the Docker Containers
Use Docker Compose to build and run the containers:
```sh
docker-compose up --build
```
#### Test the router
```sh
# client
curl http://localhost:8080/health
{"status":"healthy"}
```
```sh
#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.
```go
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:
```sh
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`.
```go
var secretKey = []byte("vyPcARcpHaov7o7aU1kDcLHjR0ZR9+UWx/TqtCvhl+g=") // ❯ openssl rand -base64 32
```
You can also modify the claims [rfc7519](https://datatracker.ietf.org/doc/html/rfc7519#section-4).
```go
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](https://dinochiesa.github.io/jwt/) To verify jwt signatures and general work with JWT.
### Use the JWT Token to Authenticate
Replace `` with the token generated in the previous step and use it to authenticate and access the API Gateway:
```sh
# client
export TOKEN=''
curl -H "Authorization: Bearer $TOKEN" http://localhost:8080/api/test
Hello from backend
```
```sh
# 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:
```sh
#!/bin/bash
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:
```sh
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](LICENSE).