How to Implement JWT Authentication in Go? - I

How to Implement JWT Authentication in Go? - I

What is?JWT authentication

JWT (short for JSON Web Token) authentication is a popular method for securing web applications and APIs. A JWT is a digitally signed token that contains a set of claims or statements about a user, such as their identity or authorization level. When a user logs in to a web application, the server generates a JWT and sends it back to the client, storing it in a cookie or local storage. The client then sends the JWT with each subsequent request to the server, which verifies the token and uses the user data in the token’s claims to authorize the request.

Why use JWT in Go

JWT is a widely used authentication standard supported by many programming languages and frameworks. Using JWT in Go can simplify authentication and provide a secure way to transmit user data between the client and server. Go’s strong typing and support for concurrency make it well-suited for building scalable and secure web applications, and using JWT can be a useful tool in this regard.

Overview of the blog

In this blog, we will explore how to implement JWT authentication in a Go web application. We will start by setting up the project and installing the required packages. Then, we will look at how to generate a JWT token and how to authenticate it. We will also implement a middleware to protect our routes, and look at how to store the JWT in a cookie for added security. By the end of this blog, you should have a good understanding of how to use JWT authentication in your Go web applications.

Installing Go and dependencies

Before we can begin implementing JWT authentication in our Go web application, we first need to make sure that Go is installed on our system. You can download and install the latest version of Go from the official Go website: golang.org/dl . You can follow our guide on how to install and set up Go: https://rekib-ahmed023.hashnode.dev/installing-and-setting-up-go-for-development

Once Go is installed, we can create a new project directory and initialize it as a Go module. We can do this by running the following commands in our terminal:

mkdir go-jwt-authentication

cd go-jwt-authentication

go mod init go-jwt-authentication

This will create a new directory called go-jwt-authentication, and initialize it as a Go module with the module path go-jwt-authentication.

We will also need to install some additional packages to work with JWT in Go. The two main packages we will be using are jwt-go for generating and verifying JWT tokens, and gin for handling HTTP requests and routing. We can install these packages using the go get command:

go get github.com/dgrijalva/jwt-go

go get github.com/gin-gonic/gin

Creating a new project

Now that we have our project directory set up and our dependencies installed, we can start creating our Go web application. We can create a new file called main.go in the root directory of our project, and start by importing the necessary packages:

package main


import (
? ?"fmt"
? ?"net/http"
? ?"github.com/dgrijalva/jwt-go"
? ?"github.com/gin-gonic/gin"
)        

Adding required packages

Next, we can define our main function and start configuring our HTTP server using the gin package:

To start the project, run the following command:

go run main.go

We will come back to defining our routes in later sections of the blog. For now, we have successfully set up our Go project and installed the necessary packages to start implementing JWT authentication in our web application.

Project Structure

When building any Go project, it’s important to follow a well-organized directory structure to maintain code readability, scalability, and maintainability. Here’s an example project structure we’ll be following for our JWT authentication implementation:

├── controllers

│?├── authController.go

│?└── userController.go

├── database

│?└── connection.go

├── helpers

│?├── config.go

│?├── cookieHelper.go

│?└── tokenHelper.go

├── middleware

│?└── authMiddleware.go

├── models

│?└── userModel.go

├── routes

│?├── authRouter.go

│?└── userRouter.go

├── serializers

│?└── serializers.go

├── go.mod

├── go.sum

├── main.go

└── Makefile

This project structure organizes the code by functionality, separating the database connection code from the controllers and middleware code. The routes directory contains the routing configuration for the API endpoints, while the models directory contains the data models used in the application. The helpers directory contains utility functions for handling JWT tokens and cookies, while the serializers directory contains functions for serializing and deserializing data between the application and the client.

Creating User Model

In this section, we will create a User model using Go's gorm package. The User model will define the fields that we want to store in our database for each user. We'll be using the gorm.Model struct, which contains the default fields of id, created_at, updated_at, and deleted_at.

Our User model will also include the following fields:

  • FirstName (string): The first name of the user.
  • LastName (string): The last name of the user.
  • Email (string): The email address of the user. We'll also add a unique constraint to ensure that there are no duplicate email addresses in the database.
  • Password (string): The hashed password of the user.

Here’s what the User model implementation might look like:

package models


import (
? ?"gorm.io/gorm"
)


type User struct {
? ?gorm.Model
? ?FirstName string `json:"first_name" validate:"required"`
? ?LastName? string `json:"last_name" validate:"required"`
? ?Email? ? ?string `gorm:"unique" json:"email" validate:"required,email"`
? ?Password? string `json:"password" validate:"required"`
}        

In this implementation, we’ve defined the fields using struct tags, which are used to add metadata to the struct fields. We’ve added the json tag to specify the JSON key for each field, and the validate tag to add validation rules for each field. We've also added the gorm tag to specify the database constraints for the Email field.

By defining our model using struct tags, we can easily serialize and deserialize our model to and from JSON, and we can also easily validate the incoming data before storing it in our database.

Connecting to the Database

Once we have our project structure set up and our user model ready, we can connect to our database using Go’s gorm package. We will create a connection.go file in the database directory, which will handle the database connection and provide a DB object that we can use throughout the application.

Here, we will be using Docker to run our Postgres container. First, make sure that Docker is installed on your system. You can download and install Docker from the official Docker website: docker.com/get-started .

Once Docker is installed, we can create a new container for our Postgres database using the following command:

docker run --name postgres15 -p 5433:5432 -e POSTGRES_USER=myuser -e POSTGRES_PASSWORD=mypassword -d postgres:15-alpine

To simplify the setup process, we can create a Makefile that includes the necessary commands to run the PostgreSQL container and create a new database. This way, we can quickly and easily set up our database without having to manually execute each command.

Here is an example of what the Makefile might look like:


ENV := $(PWD)/.env


include $(ENV)


postgresinit:
? ?docker run --name postgres15 -p $(DB_PORT):5432 -e POSTGRES_USER=$(DB_USER) -e POSTGRES_PASSWORD=$(DB_PASSWORD) -d postgres:15-alpine


postgres:
? ?docker exec -it postgres15 psql


createdb:
? ?docker exec -it postgres15 createdb --username=$(DB_USER) --owner=$(DB_USER) $(DB_NAME)


dropdb:
? ?docker exec -it postgres15 dropdb $(DB_NAME)


.PHONY: postgresinit postgres createdb dropdb        

Next, we can create a connection.go file in the database directory with the following code:

Continue here

要查看或添加评论,请登录

社区洞察

其他会员也浏览了