Table of contents
1.
Introduction
2.
Gin
3.
JWT
4.
Set up the GIn Project
5.
Set up the JWT in Gin
6.
Frequently Asked Questions
6.1.
What is Gin?
6.2.
Gin is based on which programming language?
6.3.
What is JWT?
6.4.
What is a token?
6.5.
How do we verify the authentication in JWT?
6.6.
Can we use JWT authentication with any other web framework?
7.
Conclusion
Last Updated: Mar 27, 2024
Hard

Gin - Setting up a JSON Web Token (JWT)

Author dhananjay
0 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

Golang/Go is one of the most popular programming languages worldwide. Go is used by various programmers and developers due to its versatility and benefits. Go is an open-source programming language developed by Google in 2009. Due to its efficiency, simplicity, and readability features, Go quick;y became popular among developers.

gin JSON Web Token (JWT)

This blog will teach how to set up the JWT authentication in a Golang project with the help of Gin. But first, let's talk about Gin and JWT.

Gin

Gin is an HTTP Web framework based on Go/Golang to develop microservices or web services. Gin is a web framework we can use to create API or middleware. Gin is a higher-performance and lightweight framework, and they claim to be 40 times faster than the other HTTP web framework. 

We will show you how to set up the JWT authentication with the Gin.

JWT

JWT stands for JSON Web Tokens. JWT is an authentication process that helps us securely transmit data or information between client and server as JSON objects. JSON is the data type we use to share information between two parties with the help of APIs. 

A token is a long string that contains information either in encrypted form or unencrypted, depending on the information. But JWT is digitally signed with a secret key to verify the user's authentication.

Let's understand the structure of JWT.

 JSON Web Tokens

A JWT is divided into three parts with a dot(.) at the end of the string. The first half of the string is a header, the second part is the payload, and the third is the signature.

Header

The header contains information about the token type, JWT, and the algorithm used to sign the token, like RSA, HMAC, etc.
 

Payload

The second part, the payload, contains the claims information. A claim is an information about the user, like username or password, and additional information, like token expiration time, etc.
 

Signature

This is the digitally signed signature to provide authentication. These signatures prove that the information we receive is from an authentic source or has not been tampered with during the transmission or communication.
 

We can create these digital signatures with the secret key and a secure algorithm like HMAC, SHA256, etc.

Below is the image of the JWT debugger to showcase an example.

JWT debugger

The text in red is the header, the text in purple is the payload, and the text in cyan is the signature in the encoded state. You can see the decoded version on the right side of the respective part of the token.

Set up the GIn Project

Before we teach how to apply the JWT authentication in Gin, let's set up the basic project and install some dependencies.

  • First, you must check whether Go is installed on your system.
go version

If you have installed Go in the system, it will show you the version; if it's outdated, you must update it.
 

  • Then, you need to create a root folder that will store your go files, and you need to open that folder in your code editor; we will use VS CODE for this example.
     
  • Then open the terminal in the editor and type the following code to initialize the project,
go mod init your_project_name

 

  • Once done, you must install the Gin and JWT packages to use GIn and JWT methods and syntax in your project. Type the following code in the terminal.
go get -u github.com/gin-gonic/gin
go get github.com/dgrijalva/jwt-go

 

  • You will see two files in your project folder named go.mod and go.sum, which means everything is successfully installed in the project.

 

Now we are all set to implement our project.

Create a main.go file to in the root folder of your project. To check if your application is running, copy and paste the following code.

package main


import "github.com/gin-gonic/gin"


func main() {
    router := gin.Default()
    router.GET("/sample", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "Your application is running",
        })
    })
    router.Run()
}

 

We will discuss the code further in the blog; for now, you need to check if it is giving the following output on localhost:8080/sample in your browser.

If it is running, then you are good to go and can create the HTML template for your project.

Set up the JWT in Gin

First, we need to create a UserCredentials folder in the root folder, and in this folder, we will create a file named usercred.go. In usercred.go, we declare the struct of the user’s email and password and the data type of the user's credentials.

package UserCredentials


type UserCredentials struct {
    Email string `form:"email"`
    Password string `form:"password"`
}

 

We will create a service folder in the root folder to create login and JWT services. Our file name for login will be loginservice.go, in which we will code two functions StaticLoginService() and UserLogin(). In the StaticLoginService() function, we will declare the user's email and password value. In UserLogin(), we will validate the email and password provided as input from the user with already stored information.

package service

type LoginService interface {
    UserLogin(email string, password string) bool
}
type loginInformation struct {
    email    string
    password string
}


func StaticLoginService() LoginService {
    return &loginInformation{
        email:    "testingemail@gmail.com",
        password: "Coding Ninjas Studio",
    }
}
func (info *loginInformation) UserLogin(email string, password string) bool {
    return info.email == email && info.password == password
}

 

Now, in the same service folder, we will create a JWTAuthentication.go file to generate and validate the user's token. This is where our generation of the secret key and to generate and validate the token will take place.

package GinServices

import (
    "fmt"
    "os"
    "time"


    "github.com/dgrijalva/jwt-go"
)


type JWTService interface {
    TokenGenerate(email string, isUser bool) string
    TokenValidate(token string) (*jwt.Token, error)
}
type authCustomClaims struct {
    Name string `json:"name"`
    User bool   `json:"user"`
    jwt.StandardClaims
}


type jwtServices struct {
    privateKey string
    issure     string
}


func JWTAuthService() JWTService {
    return &jwtServices{
        privateKey: getSecretKey(),
        issure:     "Drake",
    }
}


func getSecretKey() string {
    secret := os.Getenv("JWT_SECRET")
    if secret == "" {
        secret = "secretkey"
    }
    return secret
}


func (service *jwtServices) TokenGenerate(email string, isUser bool) string {
    claims := &authCustomClaims{
        email,
        isUser,
        jwt.StandardClaims{
            ExpiresAt: time.Now().Add(time.Hour * 48).Unix(),
            Issuer:    service.issure,
            IssuedAt:  time.Now().Unix(),
        },
    }
    token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)


    //encoded the web token
    t, err := token.SignedString([]byte(service.privateKey))
    if err != nil {
        panic(err)
    }
    return t
}


func (service *jwtServices) TokenValidate(encodedToken string) (*jwt.Token, error) {
    return jwt.Parse(encodedToken, func(token *jwt.Token) (interface{}, error) {
        if _, isvalid := token.Method.(*jwt.SigningMethodHMAC); !isvalid {
            return nil, fmt.Errorf("Invalid token", token.Header["alg"])
        }
        return []byte(service.privateKey), nil
    })
}

 

Our private key will be equal to secretKey, which we will use to sign the token and the name of the person who will issue us this token will be Drake. In the token generated () function, we will generate the claim for the token and then will encode that token with a private key with the HS256 algorithm. After that, we will validate the token in the TokenValidate function.
Our next step will be to create a controller folder in the root folder and then create a logincontroller.go file where we will call the loginuser() function and TokenGenerate() function to take the user input and validate the user input.

We will call the TokenGenerate() function to generate the token if the user input credentials are valid.

package Controller

import (
    "jwt-auth-go/GinServices"
    "jwt-auth-go/UserCredentials"


    "github.com/gin-gonic/gin"
)


type LoginController interface {
    LoginProcess(ctx *gin.Context) string
}


type loginController struct {
    loginService GinServices.LoginService
    jWtService   GinServices.JWTService
}


func LoginHandler(loginService GinServices.LoginService,
    jWtService GinServices.JWTService) LoginController {
    return &loginController{
        loginService: loginService,
        jWtService:   jWtService,
    }
}


func (Controller *loginController) LoginProcess(ctx *gin.Context) string {
    var credential UserCredentials.UserCredentials
    err := ctx.ShouldBind(&credential)
    if err != nil {
        return "no data found"
    }
    isUserAuthenticated := Controller.loginService.UserLogin(credential.Email, credential.Password)
    if isUserAuthenticated {
        return Controller.jWtService.TokenGenerate(credential.Email, true)
    }
    return ""
}


Our next step will be to create a middleware for the JWTauthorization. To do that, we will create a middleware folder in the root folder, and in that folder, we will create a jwtmiddelware.go file.

package Middlewares


import (
    "fmt"
    "jwt-auth-go/GinServices"
    "net/http"


    "github.com/dgrijalva/jwt-go"
    "github.com/gin-gonic/gin"
)


func AuthorizeJWT() gin.HandlerFunc {
    return func(c *gin.Context) {
        const BEARER_SCHEMA = "Bearer"
        authHeader := c.GetHeader("Authorization")
        tokenString := authHeader[len(BEARER_SCHEMA):]
        token, err := GinServices.JWTAuthService().TokenValidate(tokenString)
        if token.Valid {
            claims := token.Claims.(jwt.MapClaims)
            fmt.Println(claims)
        } else {
            fmt.Println(err)
            c.AbortWithStatus(http.StatusUnauthorized)
        }


    }
}

 

Now we are all set to run our JWT authentication; now we need to update our main.go file and call all the necessary functions to generate our web token.

package main

import (
    "jwt-auth-go/Controller"
    "jwt-auth-go/GinServices"
    "net/http"


    "github.com/gin-gonic/gin"
)

func main() {
    var loginService GinServices.LoginService = GinServices.StaticLoginService()
    var jwtService GinServices.JWTService = GinServices.JWTAuthService()
    var loginController Controller.LoginController = Controller.LoginHandler(loginService, jwtService)


    Ginserver := gin.New()


    Ginserver.POST("/login", func(ctx *gin.Context) {
        token := loginController.LoginProcess(ctx)
        if token != "" {
            ctx.JSON(http.StatusOK, gin.H{
                "token": token,
            })
        } else {
            ctx.JSON(http.StatusUnauthorized, nil)
        }
    })
    Ginserver.Run()

}

 

 We will be using insomnia to check out the output you can use any application you want, like postman, to test your API.

insomnia api testing

 

As you can see, we have successfully generated a web token on the right side of the image now; let's decode this token with the help jwt debugger online to verify the information.

jwt token decoding

 

As you can see, the information is decoded on the right side of the image. This means we have successfully created the JWT authentication token in Gin.

Frequently Asked Questions

What is Gin?

Various developers use Gin as an open-source web framework to create microservices and API endpoints.

Gin is based on which programming language?

Gin is based on Go/Golang programming language.

What is JWT?

JWT stands for JSON Web Tokens. JWT is an authentication process that helps us securely transmit data or information between client and server as JSON objects.

What is a token?

A token is a long string that contains information either in encrypted form or unencrypted, depending on the information.

How do we verify the authentication in JWT?

With the help of a digitally signed signature included in the token, we can verify the authenticity of the token.

Can we use JWT authentication with any other web framework?

Yes, you can set up the JWT authentication with any web framework which supports the JWT.

Conclusion

In this blog, we discussed Gin and JWT. We have also learned how to generate and validate the tokens when a user logs into his account in Gin.

To learn more about Gin, check out the following articles

 

To learn more about DSA, competitive coding, and many more knowledgeable topics, please look into the guided paths on Coding Ninjas Studio. Also, you can enroll in our courses and check out the mock test and problems available to you. Please check out our interview experiences and interview bundle for placement preparations.

Happy Coding!

Live masterclass