Home  >  Article  >  Backend Development  >  Using Gin framework to implement two-factor authentication function

Using Gin framework to implement two-factor authentication function

PHPz
PHPzOriginal
2023-06-22 12:45:021143browse

Two-factor authentication has become an essential feature of network security, which can greatly enhance the security of your account. In this article, we will introduce how to use the Gin framework to implement two-factor authentication functionality.

The Gin framework is a lightweight web framework that has the advantages of high performance, ease of use and flexibility. It supports RESTful API, middleware, routing groups, template rendering and other functions, and has good documentation and examples, making it one of the most popular Go language web frameworks.

Before you start, please make sure you have installed the Go language development environment and configured the corresponding GOPATH and PATH environment variables.

First, we need to create a new Gin project. Enter the following command on the command line:

$ mkdir gin-auth
$ cd gin-auth
$ go mod init gin-auth

Next, we need to install the Gin framework and other dependent packages. Type the following command in the console:

$ go get -u github.com/gin-gonic/gin
$ go get -u github.com/gin-contrib/sessions
$ go get -u github.com/google/uuid
  • gin is the Gin framework itself.
  • gin-contrib/sessions is the Session middleware of the Gin framework, used to handle Session-related tasks.
  • uuid is a Go language library developed by Google for generating UUID. Used in this article to generate two-factor authentication verification codes.

Now, we can start implementing our two-factor authentication feature.

We first need to write the login page and the code to handle the login request, as shown below:

package main

import (
    "net/http"

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

func main() {
    router := gin.Default()

    // 使用sessions中间件
    store := sessions.NewCookieStore([]byte("secret"))
    router.Use(sessions.Sessions("mysession", store))

    router.GET("/", func(c *gin.Context) {
        c.HTML(http.StatusOK, "login.html", nil)
    })

    router.POST("/", func(c *gin.Context) {
        username := c.PostForm("username")
        password := c.PostForm("password")

        // TODO: 验证用户名和密码是否正确

        // 将用户名保存到Session中
        session := sessions.Default(c)
        session.Set("username", username)
        session.Save()

        c.Redirect(http.StatusFound, "/second-factor")
    })

    router.Run(":8080")
}

In the above code, we use the Gin framework's gin.Default()Function creates a basic router. Then, we use the sessions.NewCookieStore function to create a Cookie Store that stores Session to store the user's Session information. We used Session middleware in the router middleware and named it mysession.

In the home page routing, we will render the login page through the c.HTML function. In the login route, we get the username and password entered by the user and then validate them in a function we implement later. If the authentication is successful, we save the username in the Session and redirect the user to the second authentication page.

Next, we will write the page and function for the second authentication. Here, we verify whether we have logged in through Session. If logged in, the secondary authentication page is displayed and a random 6-digit verification code is generated. The verification code will be saved in the Session and sent to the user via SMS, email, or security token.

// 定义一个中间件,用于检查Session中是否保存了该用户的用户名
func AuthRequired() gin.HandlerFunc {
    return func(c *gin.Context) {
        session := sessions.Default(c)
        username := session.Get("username")
        if username == nil {
            c.Redirect(http.StatusFound, "/")
            return
        }
        c.Next()
    }
}

func generateCode() string {
    code := uuid.New().String()
    code = strings.ReplaceAll(code, "-", "")
    code = code[:6]
    return code
}

func sendCode(username string, code string) error {
    // TODO: 将验证码发送给用户
    return nil
}

func main() {
    router := gin.Default()

    // ...

    router.GET("/second-factor", AuthRequired(), func(c *gin.Context) {
        session := sessions.Default(c)
        username := session.Get("username").(string)

        code := generateCode()

        // 将二次认证验证码保存到Session
        session.Set("second-factor-code", code)
        session.Save()

        // 发送二次认证验证码
        err := sendCode(username, code)
        if err != nil {
            c.String(http.StatusInternalServerError, "发送二次认证验证码失败")
        }

        // 渲染二次认证视图
        c.HTML(http.StatusOK, "second-factor.html", nil)
    })

    router.POST("/second-factor", AuthRequired(), func(c *gin.Context) {
        session := sessions.Default(c)
        code := session.Get("second-factor-code").(string)
        inputCode := c.PostForm("code")

        // 验证二次认证验证码是否正确
        if code != inputCode {
            c.String(http.StatusBadRequest, "验证码不正确")
            return
        }

        c.Redirect(http.StatusFound, "/dashboard")
    })

    router.Run(":8080")
}

In the above code, we define a middleware named AuthRequired to check whether a logged-in user exists in the Session. In our second route, we use this middleware to redirect the user to the login page if the logged in user is not found in the Session.

We use a function called generateCode to generate a 6-digit verification code and use the sendCode function to send that verification code to the user. In our actual application, this verification code can be sent using SMS, email, or security token.

We use a POST request and the token in the second route to verify whether the user's secondary authentication code is correct. If the authentication code is correct, the user is redirected to the control panel page.

代码已经完成了,现在可以创建一些模板文件来呈现登录、二次验证和控制面板页面了。下面是示例模板文件,你可以根据自身需求对其进行修改。

02fab53d219d289dfbb04d9d45c84f32
aba7b36f87decd50b18c7e3e3c150106
46d1a6bdc802636878ae98bee68f7971
93f0f5c25f18dab9d176bd4f6de5d30e

<meta charset="UTF-8">
<title>Login</title>

9c3bca370b5104690d9ef395f2c5f8d1
6c04bd5ca3fcae76e30b72ad730ca86d

<form method="post" action="/">
  <label>
    用户名:
    <input type="text" name="username" />
  </label>
  <br />
  <label>
    密码:
    <input type="password" name="password" />
  </label>
  <br />
  <button type="submit">登录</button>
</form>

36cc49f0c466276486e50c850b7e4956
73a6ac4ed44ffec12cee46588e518a5e

55fa48996bcb623ea4d16b6c5e0cf545
aba7b36f87decd50b18c7e3e3c150106
46d1a6bdc802636878ae98bee68f7971
93f0f5c25f18dab9d176bd4f6de5d30e

<meta charset="UTF-8">
<title>Second Factor Authentication</title>

3c7b149cc556f883a18b3c490b028d4e
6c04bd5ca3fcae76e30b72ad730ca86d

<form method="post" action="/second-factor">
  <p>
    请验证您的身份。
  </p>
  <p>
    一个6位数字的验证码已经发送到您的邮件或手机上。
    <br />
    请输入该验证码以完成二次认证:
  </p>
  <label>
    验证码:
    <input type="text" name="code" />
  </label>
  <br />
  <button type="submit">验证</button>
</form>

36cc49f0c466276486e50c850b7e4956
73a6ac4ed44ffec12cee46588e518a5e

658817a67e64a475cd8b0397d9e9fb9e
aba7b36f87decd50b18c7e3e3c150106
46d1a6bdc802636878ae98bee68f7971
93f0f5c25f18dab9d176bd4f6de5d30e

<meta charset="UTF-8">
<title>Dashboard</title>

9c3bca370b5104690d9ef395f2c5f8d1
6c04bd5ca3fcae76e30b72ad730ca86d

<h1>欢迎访问控制面板</h1>

36cc49f0c466276486e50c850b7e4956
73a6ac4ed44ffec12cee46588e518a5e

现在,我们的Gin应用程序就已经完成了。它使用Session中间件实现了用户认证机制,并使用了二次认证功能来增强安全性。

The above is the detailed content of Using Gin framework to implement two-factor authentication function. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn