An open API service indexing awesome lists of open source software.

https://github.com/cryognar/jwtgo

πŸ”₯ Example of microservice JWT authentication using MongoDB and clean architecture principles.
https://github.com/cryognar/jwtgo

bcrypt boilerplate clean-architecture cleanenv docker docker-compose gin go golang grpc jwt layout logrus microservice mongodb nginx protobuf reverse-proxy

Last synced: 3 months ago
JSON representation

πŸ”₯ Example of microservice JWT authentication using MongoDB and clean architecture principles.

Awesome Lists containing this project

README

        

# jwtgo

A Go (Golang) backend clean architecture project with Gin, MongoDB and JWT Authentication middleware.

The project was created for educational purposes and is not ideal. It has its shortcomings, which are gradually being corrected.

## Project architecture
The architecture of a web application consists of these layers:
- Reverse Proxy
- API Gateway
- Microservice
- Database

The architecture of the microservice application consists of these layers:
- Server
- Service
- Repository

![Image](https://raw.githubusercontent.com/Astagnar/jwtgo/refs/heads/main/assets/architecture.png)

The API is accessed via Reverse Proxy, in our case it is Nginx. It handles all incoming requests and prevents access to microservices and API gateway directly.

## Major packages used in project
- **[Gin](https://pkg.go.dev/github.com/gin-gonic/gin)**: Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API with much better performance -- up to 40 times faster. If you need smashing performance, get yourself some Gin.
- **[gRPC](https://pkg.go.dev/google.golang.org/grpc)**: The Go implementation of gRPC: A high performance, open source, general RPC framework that puts mobile and HTTP/2 first. For more information see the Go gRPC docs, or jump directly into the quick start.
- **[protobuf](https://pkg.go.dev/google.golang.org/protobuf)**: Go support for Google's protocol buffers.
- **[MongoDB](https://pkg.go.dev/go.mongodb.org/mongo-driver)**: The Official Golang driver for MongoDB.
- **[JWT](https://pkg.go.dev/github.com/golang-jwt/jwt/v5)**: Go implementation of JSON Web Tokens (JWT).
- **[Cleanenv](https://pkg.go.dev/github.com/ilyakaznacheev/cleanenv)**: Clean and minimalistic environment configuration reader for Golang.
- **[Bcrypt](https://pkg.go.dev/golang.org/x/crypto/bcrypt)**: Package bcrypt implements Provos and Mazières's bcrypt adaptive hashing algorithm.
- **[Logrus](https://pkg.go.dev/github.com/sirupsen/logrus)**: Structured, pluggable logging for Go.
- **[Validator](https://pkg.go.dev/github.com/go-playground/validator/v10)**: Go Struct and Field validation, including Cross Field, Cross Struct, Map, Slice and Array diving.

## Request flow without JWT authentication middleware
![Image](https://raw.githubusercontent.com/Astagnar/jwtgo/refs/heads/main/assets/without-jwt.png)

## Request flow with JWT authentication middleware
![Image](https://raw.githubusercontent.com/Astagnar/jwtgo/refs/heads/main/assets/with-jwt.png)

## How to run the project?
First, download it and navigate to the root directory:
```bash
# Move to your workspace
cd your-workspace

# Clone the project into your workspace
git clone https://github.com/Astagnar/jwtgo.git

# Move to the project root directory
cd jwtgo
```

### Run with Docker
- Create a `.env` file, similar to `.env.sample`.
- Install the [Docker](https://www.docker.com/get-started/), [Protoc](https://grpc.io/docs/protoc-installation/), [Taskfile](https://taskfile.dev/installation/) if it is not installed on your computer.
- Fill in the `.env` file with your data.
- Run the application build with the following command:

```bash
task build
```
- Access API using http://localhost.

## Examples of API requests and responses
### SignUp endpoint
- Request:
```
curl --location 'http://localhost/auth/signup' \
--header 'Content-Type: application/json' \
--data-raw '{
"email": "[email protected]",
"password": "securepassword"
}'
```

- Response:
```
HTTP/1.1 200 OK
Content-Type: application/json
```
```json
{
"message": "User successfully registered"
}
```

### SignIn endpoint
- Request:
```
curl --location 'http://localhost/auth/signin' \
--header 'Content-Type: application/json' \
--data-raw '{
"email": "[email protected]",
"password": "securepassword"
}'
```

- Response:
```
HTTP/1.1 200 OK
Content-Type: application/json
Set-Cookie: access_token=access_token; Path=/; HttpOnly; SameSite=Strict
Set-Cookie: refresh_token=refresh_token; Path=/; HttpOnly; SameSite=Strict
```
```json
{
"message": "User successfully logged in"
}
```

### SignOut endpoint
- Request:
```
curl --location 'http://localhost/auth/signout' \
--header 'Content-Type: application/json' \
-b 'access_token=access_token; refresh_token=refresh_token'
```

- Response:
```
HTTP/1.1 200 OK
Content-Type: application/json
Set-Cookie: access_token=access_token; Path=/; HttpOnly; SameSite=Strict
Set-Cookie: refresh_token=refresh_token; Path=/; HttpOnly; SameSite=Strict
```
```json
{
"message": "User successfully logged out"
}
```

### Refresh endpoint
- Request:
```
curl --location 'http://localhost/auth/refresh' \
--header 'Content-Type: application/json' \
-b 'access_token=access_token; refresh_token=refresh_token'
```

- Response:
```
HTTP/1.1 200 OK
Content-Type: application/json
Set-Cookie: access_token=access_token; Path=/; HttpOnly; SameSite=Strict
Set-Cookie: refresh_token=refresh_token; Path=/; HttpOnly; SameSite=Strict
```
```json
{
"message": "Tokens successfully updated"
}
```

## Complete project folder structure
```
β”œβ”€β”€ build
β”‚ └── package
β”‚ β”œβ”€β”€ api.Dockerfile
β”‚ β”œβ”€β”€ auth.Dockerfile
β”‚ └── user.Dockerfile
β”œβ”€β”€ cmd
β”‚ β”œβ”€β”€ api
β”‚ β”‚ └── main.go
β”‚ β”œβ”€β”€ auth
β”‚ β”‚ └── main.go
β”‚ └── user
β”‚ └── main.go
β”œβ”€β”€ configs
β”‚ └── nginx.conf
β”œβ”€β”€ deployments
β”‚ └── docker-compose.yaml
β”œβ”€β”€ internal
β”‚ β”œβ”€β”€ app
β”‚ β”‚ β”œβ”€β”€ api
β”‚ β”‚ β”‚ β”œβ”€β”€ config
β”‚ β”‚ β”‚ β”‚ └── config.go
β”‚ β”‚ β”‚ β”œβ”€β”€ controller
β”‚ β”‚ β”‚ β”‚ └── http
β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ dto
β”‚ β”‚ β”‚ β”‚ β”‚ └── user.go
β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ mapper
β”‚ β”‚ β”‚ β”‚ β”‚ └── user.go
β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ middleware
β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ security.go
β”‚ β”‚ β”‚ β”‚ β”‚ └── validation.go
β”‚ β”‚ β”‚ β”‚ └── v1
β”‚ β”‚ β”‚ β”‚ └── auth.go
β”‚ β”‚ β”‚ └── main.go
β”‚ β”‚ β”œβ”€β”€ auth
β”‚ β”‚ β”‚ β”œβ”€β”€ config
β”‚ β”‚ β”‚ β”‚ └── config.go
β”‚ β”‚ β”‚ β”œβ”€β”€ interface
β”‚ β”‚ β”‚ β”‚ └── service
β”‚ β”‚ β”‚ β”‚ └── auth.go
β”‚ β”‚ β”‚ β”œβ”€β”€ server
β”‚ β”‚ β”‚ β”‚ └── grpc
β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ dto
β”‚ β”‚ β”‚ β”‚ β”‚ └── user.go
β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ mapper
β”‚ β”‚ β”‚ β”‚ β”‚ └── user.go
β”‚ β”‚ β”‚ β”‚ └── v1
β”‚ β”‚ β”‚ β”‚ └── auth.go
β”‚ β”‚ β”‚ β”œβ”€β”€ service
β”‚ β”‚ β”‚ β”‚ └── auth.go
β”‚ β”‚ β”‚ └── main.go
β”‚ β”‚ └── user
β”‚ β”‚ β”œβ”€β”€ adapter
β”‚ β”‚ β”‚ └── mongodb
β”‚ β”‚ β”‚ β”œβ”€β”€ entity
β”‚ β”‚ β”‚ β”‚ └── user.go
β”‚ β”‚ β”‚ β”œβ”€β”€ mapper
β”‚ β”‚ β”‚ β”‚ └── user.go
β”‚ β”‚ β”‚ └── repository
β”‚ β”‚ β”‚ └── user.go
β”‚ β”‚ β”œβ”€β”€ config
β”‚ β”‚ β”‚ └── config.go
β”‚ β”‚ β”œβ”€β”€ entity
β”‚ β”‚ β”‚ └── user.go
β”‚ β”‚ β”œβ”€β”€ interface
β”‚ β”‚ β”‚ β”œβ”€β”€ repository
β”‚ β”‚ β”‚ β”‚ └── user.go
β”‚ β”‚ β”‚ └── service
β”‚ β”‚ β”‚ └── user.go
β”‚ β”‚ β”œβ”€β”€ server
β”‚ β”‚ β”‚ └── grpc
β”‚ β”‚ β”‚ β”œβ”€β”€ dto
β”‚ β”‚ β”‚ β”‚ └── user.go
β”‚ β”‚ β”‚ β”œβ”€β”€ mapper
β”‚ β”‚ β”‚ β”‚ └── user.go
β”‚ β”‚ β”‚ └── v1
β”‚ β”‚ β”‚ └── user.go
β”‚ β”‚ β”œβ”€β”€ service
β”‚ β”‚ β”‚ └── user.go
β”‚ β”‚ └── main.go
β”‚ └── pkg
β”‚ β”œβ”€β”€ error
β”‚ β”‚ β”œβ”€β”€ auth.go
β”‚ β”‚ β”œβ”€β”€ jwt.go
β”‚ β”‚ β”œβ”€β”€ repository.go
β”‚ β”‚ └── server.go
β”‚ β”œβ”€β”€ interface
β”‚ β”‚ └── service
β”‚ β”‚ β”œβ”€β”€ jwt.go
β”‚ β”‚ └── password.go
β”‚ β”œβ”€β”€ proto
β”‚ β”‚ β”œβ”€β”€ auth
β”‚ β”‚ β”‚ β”œβ”€β”€ auth.pb.go
β”‚ β”‚ β”‚ └── auth_grpc.pb.go
β”‚ β”‚ └── user
β”‚ β”‚ β”œβ”€β”€ user.pb.go
β”‚ β”‚ └── user_grpc.pb.go
β”‚ β”œβ”€β”€ request
β”‚ β”‚ β”œβ”€β”€ schema
β”‚ β”‚ β”‚ └── response.go
β”‚ β”‚ └── response.go
β”‚ └── service
β”‚ β”œβ”€β”€ schema
β”‚ β”‚ └── jwt.go
β”‚ β”œβ”€β”€ jwt.go
β”‚ └── password.go
β”œβ”€β”€ pkg
β”‚ β”œβ”€β”€ client
β”‚ β”‚ └── mongodb.go
β”‚ β”œβ”€β”€ logging
β”‚ β”‚ └── logger.go
β”‚ └── proto
β”‚ β”œβ”€β”€ auth
β”‚ β”‚ └── auth.proto
β”‚ └── user
β”‚ └── user.proto
β”œβ”€β”€ .env
β”œβ”€β”€ .gitignore
β”œβ”€β”€ go.mod
β”œβ”€β”€ go.sum
β”œβ”€β”€ LICENSE
β”œβ”€β”€ README.md
└── taskfile.yaml
```