Maison  >  Article  >  développement back-end  >  Utiliser le framework Gin pour implémenter la fonction d'authentification à deux facteurs

Utiliser le framework Gin pour implémenter la fonction d'authentification à deux facteurs

PHPz
PHPzoriginal
2023-06-22 12:45:021163parcourir

L'authentification à deux facteurs est devenue une fonctionnalité essentielle de la sécurité du réseau, qui peut grandement améliorer la sécurité de votre compte. Dans cet article, nous présenterons comment utiliser le framework Gin pour implémenter la fonctionnalité d'authentification à deux facteurs.

Le framework Gin est un framework Web léger qui présente les avantages de hautes performances, de facilité d'utilisation et de flexibilité. Il prend en charge l'API RESTful, le middleware, les groupes de routage, le rendu de modèles et d'autres fonctions, et dispose d'une bonne documentation et d'exemples, ce qui en fait l'un des frameworks Web en langage Go les plus populaires.

Avant de commencer, assurez-vous d'avoir installé l'environnement de développement du langage Go et configuré les variables d'environnement GOPATH et PATH correspondantes.

Tout d'abord, nous devons créer un nouveau projet Gin. Entrez la commande suivante dans la ligne de commande :

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

Ensuite, nous devons installer le framework Gin et d'autres packages de dépendances. Tapez la commande suivante dans la 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 est le framework Gin lui-même.
  • gin是Gin框架本身。
  • gin-contrib/sessions是Gin框架的Session中间件,用于处理Session相关任务。
  • uuid是Google开发的用于生成UUID的Go语言库。在本文中用于生成二次认证验证码。

现在,我们可以开始实现我们的双因素认证功能了。

我们首先需要编写登录页面和处理登录请求的代码,如下所示:

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")
}

上面的代码中,我们使用Gin框架的gin.Default()函数创建一个基本的路由器。然后,我们使用sessions.NewCookieStore函数创建了一个存储Session的Cookie Store,用于储存用户的Session信息。我们在路由器中间件中使用了Session中间件,并将其命名为mysession

在首页路由中,我们通过c.HTML函数将渲染出登录页面。在登录路由中,我们获取用户输入的用户名和密码,然后在稍后实现的功能中验证它们。如果验证成功,我们将用户名保存在Session中,并将用户重定向到第二种认证页面。

接下来,我们将编写第二次认证的页面和功能。在这里,我们通过Session验证是否已经登录,如果登录,则显示二次认证页面并生成一个随机的6位数字验证码。该验证码将保存在Session中,并将通过短信、邮件或安全令牌等方式发送给用户。

// 定义一个中间件,用于检查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")
}

在上面的代码中,我们定义了一个名为AuthRequired的中间件,用于检查Session中是否存在已登录的用户。在我们的第二个路由中,使用该中间件,如果Session中未找到已登录的用户,则将用户重定向到登录页面。

我们使用一个名为generateCode的函数来生成6位数字的验证码,并使用sendCodegin-contrib/sessions est le middleware de session du framework Gin, utilisé pour gérer les tâches liées à la session.

uuid est une bibliothèque de langage Go développée par Google pour générer des UUID. Utilisé dans cet article pour générer des codes de vérification d'authentification à deux facteurs.

Maintenant, nous pouvons commencer à mettre en œuvre notre fonctionnalité d'authentification à deux facteurs.

Nous devons d'abord écrire la page de connexion et le code pour gérer la demande de connexion, comme indiqué ci-dessous :

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

Dans le code ci-dessus, nous utilisons la fonction gin.Default() du framework Gin pour créer un routeur de base. Ensuite, nous utilisons la fonction sessions.NewCookieStore pour créer un magasin de cookies pour stocker la session, qui est utilisé pour stocker les informations de session de l'utilisateur. Nous avons utilisé le middleware de session dans le middleware du routeur et l'avons nommé mysession.

Dans le routage de la page d'accueil, nous utilisons la fonction c.HTML pour restituer la page de connexion. Lors de la route de connexion, nous obtenons le nom d'utilisateur et le mot de passe saisis par l'utilisateur, puis les validons dans une fonction que nous implémenterons ultérieurement. Si l'authentification réussit, nous enregistrons le nom d'utilisateur dans la session et redirigeons l'utilisateur vers la deuxième page d'authentification.


Ensuite, nous écrirons la page et la fonction pour la deuxième authentification. Ici, nous vérifions si nous nous sommes connectés via la session. Si nous sommes connectés, la page d'authentification secondaire s'affiche et un code de vérification aléatoire à 6 chiffres est généré. Le code de vérification sera enregistré dans la session et envoyé à l'utilisateur par SMS, e-mail ou jeton de sécurité.

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

Dans le code ci-dessus, nous définissons un middleware nommé AuthRequired pour vérifier s'il y a un utilisateur connecté dans la session. Dans notre deuxième route, nous utilisons ce middleware pour rediriger l'utilisateur vers la page de connexion si l'utilisateur connecté n'est pas trouvé dans la session.

Nous utilisons une fonction appelée generateCode pour générer un code de vérification à 6 chiffres, et utilisons la fonction sendCode pour envoyer le code de vérification à l'utilisateur. Dans notre application actuelle, ce code de vérification peut être envoyé par SMS, e-mail ou jeton de sécurité.


Nous utilisons une requête POST et le token dans la deuxième route pour vérifier si le code d'authentification en deux étapes de l'utilisateur est correct. Si le code d'authentification est correct, l'utilisateur est redirigé vers la page du panneau de configuration.

<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>

02fab53d219d289dfbb04d9d45c84f32

aba7b36f87decd50b18c7e3e3c150106

46d1a6bdc802636878ae98bee68f7971
93f0f5c25f18dab9d176bd4f6de5d30e

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

9c3bca370b5104690d9ef395f2c5f8d1
< ;body>

<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

55fa48996bcb623ea4d16b6c5e0cf545

aba7b36f87decd50b18c7e3e3c150106

1910c9ad900e94866e07bc3452aa9c2d
93f0f5c25f18dab9d176bd4f6de5d30e

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

9c3bca370b5104690d9ef395f2c5f8d1
6c04bd5ca3fcae76e30b72ad730ca86d

<h1>欢迎访问控制面板</h1>
🎜36cc49f0c466276486e50c850b7e4956🎜73a6ac4ed44ffec12cee46588e518a5e🎜🎜e8c924a5cc9e193881d5a83e5638f6e0🎜 aba7b36f87decd50b18c7e3e3c150106🎜46d1a6bdc802636878ae98bee68f7971🎜 93f0f5c25f18dab9d176bd4f6de5d30e🎜
现在,我们的Gin应用程序就已经完成了。它使用Session中间件实现了用户认证机制,并使用了二次认证功能来增强安全性。
🎜9c3bca370b5104690d9ef395f2c5f8d1🎜 6c04bd5ca3fcae76e30b72ad730ca86d🎜rrreee🎜36cc49f0c466276486e50c850b7e4956🎜Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn