Create your first Go REST API with JWT Authentication in Gin Framework

Seef Nasrul
6 min readJun 26, 2021

--

What is JSON Web Token?

JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA.

Although JWTs can be encrypted to also provide secrecy between parties, we will focus on signed tokens. Signed tokens can verify the integrity of the claims contained within it, while encrypted tokens hide those claims from other parties. When tokens are signed using public/private key pairs, the signature also certifies that only the party holding the private key is the one that signed it.

Our simple REST API Design

so for this project, we will need to create 2 public endpoints that will be used as authentication and 1 protected endpoint that will be protected by our JWT

Login

this route will be used to authenticate the user by providing a username and password then generate and gives JSON Web Token in return

/api/login

Register

of course, because we have a login route earlier we need a way to register our login information, so it can be verified.

/api/register

for the sake of this tutorial, we will leave the registration route open. If you don't want people to be able to gain login access easily you might not want to do this.

Protected Route

this will be the route for our protected endpoints

/api/admin/user

Getting Started

to initiate our project we want to create our project dir folder and going into the directory

mkdir jwt-gin
cd jwt-gin

we can start by initiating our go.mod file to manage packages that we will be installing later on.

go mod init <your_project_name>

here’s the list of packages that we will need to install for this project.

// gin framework
go get -u github.com/gin-gonic/gin
// ORM library
go get -u github.com/jinzhu/gorm
// package that we will be used to authenticate and generate our JWT
go get -u github.com/dgrijalva/jwt-go
// to help manage our environment variables
go get -u github.com/joho/godotenv
// to encrypt our user's password
go get -u golang.org/x/crypto

Alright.. now that everything is set, we can start coding our application!

Creating our first endpoint

we can start by creating our main.go file in our root directory

touch main.go

here is the code for our starter public endpoint

and we can try to run it.

// to run the server
go run main.go

Perfect! it seems our register endpoint is working properly.

Creating Register Endpoint

Now that our register endpoint is ready, we can start creating our controller file that will contain our logic for the registration process.

create controller package dir

mkdir controllers

create controller file for our login that will be named auth.go

touch ./controllers/auth.go

and we also have to update our main.go file

now let's test it again!

Perfect!

Validation

we need to validate inputs that are coming into our register endpoint, the only input we will need are username and password.

we will be using a validation feature that comes with gin which is called binding.

if you want to know more about binding and validator

let's update our auth.go file

let's test our validation!

missing password input test :

correct input test:

Database Connection and Model

To save our credentials in our database, we need to create a database connection to our desired database, I will be using MySQL database that is already installed in my system.

let's create models package

mkdir models

this folder will contain the database connection file and all our models

database connection file

touch ./models/setup.go

Alright as you can notice in the setup.go file we will need 2 things

  1. .env file
  2. User model

Creating .env file

we can create the .env file by simply creating it in our root directory

touch .env

Making User Model

touch ./models/user.go

Alright, now that our database connection is set let's add it to our main.go file and test it!

this is what you should see in your terminal

Perfect! now we can save the credential into the database.

let's update our auth.go file

in order to save our User data we need to create the SaveUser() function in our User model but we also need to create gorm hooks BeforeSave() function that will be running the hash process to the user’s password.

let's update our user.go file

Let's test it!

Perfect, It means the credential is saved and hashed and we can use it to validate the login process!

Creating Login Endpoint

what our login endpoint going to do is very simple, it will receive a username and password, check whether it matches the credential in our database, if it does return a token, if it doesn’t return an error response.

let's add a new route to our main.go

add Login function in auth.go controller

the Login controller function will call LoginCheck function from user.go

lets add it to our user.go file

we also need to create token.go file that will contain all of our token processing functions, we will create a new directory which is called utils

mkdir utils
mkdir ./utils/token
touch ./utils/token/token.go

here’s token.go file along with several functions that we will be using later on as well.

we also need to add 2 new variables into our .env file

which is TOKEN_HOUR_LIFESPAN and API_SECRET

API_SECRET=yoursecretstring
TOKEN_HOUR_LIFESPAN=1

TOKEN_HOUR_LIFESPAN will determine how long each token will last (hour)

API_SECRET is your own secret string for signing the token

let's run and test our Login

Perfect!

Creating JWT Authentication Middleware

lets create our middleware.go file

mkdir middlewares
touch ./middlewares/middlewares.go

let's implement to our middleware to our main.go

lets add CurrentUser function in our auth.go file so we can return the current authenticated user data.

lets add GetUserByID function into our user.go

you can also notice we ran PrepareGive function to remove the hashed password string before returning it for security purposes.

let's test our protected endpoint

Perfect!

By that, it will conclude the tutorial. I hope it helps you on your personal journey as a developer.

Thank you, See you later! 😀👋

--

--