Die Zwei-Faktor-Authentifizierung ist zu einem wesentlichen Merkmal der Netzwerksicherheit geworden, das die Sicherheit Ihres Kontos erheblich verbessern kann. In diesem Artikel stellen wir vor, wie Sie das Gin-Framework verwenden, um die Zwei-Faktor-Authentifizierungsfunktionalität zu implementieren.
Gin Framework ist ein leichtes Webframework, das die Vorteile hoher Leistung, Benutzerfreundlichkeit und Flexibilität bietet. Es unterstützt RESTful API, Middleware, Routinggruppen, Vorlagenrendering und andere Funktionen und verfügt über eine gute Dokumentation und Beispiele, was es zu einem der beliebtesten Web-Frameworks der Go-Sprache macht.
Bevor Sie beginnen, stellen Sie bitte sicher, dass Sie die Go-Sprachentwicklungsumgebung installiert und die entsprechenden Umgebungsvariablen GOPATH und PATH konfiguriert haben.
Zuerst müssen wir ein neues Gin-Projekt erstellen. Geben Sie den folgenden Befehl in die Befehlszeile ein:
$ mkdir gin-auth $ cd gin-auth $ go mod init gin-auth
Als nächstes müssen wir das Gin-Framework und andere abhängige Pakete installieren. Geben Sie den folgenden Befehl in die Konsole ein:
$ go get -u github.com/gin-gonic/gin $ go get -u github.com/gin-contrib/sessions $ go get -u github.com/google/uuid
gin
ist das Gin-Framework selbst. 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位数字的验证码,并使用sendCode
gin-contrib/sessions
ist die Session-Middleware des Gin-Frameworks, die zur Abwicklung sitzungsbezogener Aufgaben verwendet wird.
uuid
ist eine von Google entwickelte Go-Sprachbibliothek zur Generierung von UUIDs. Wird in diesem Artikel zum Generieren von Bestätigungscodes für die Zwei-Faktor-Authentifizierung verwendet. Jetzt können wir mit der Implementierung unserer Zwei-Faktor-Authentifizierungsfunktion beginnen.
Wir müssen zuerst die Anmeldeseite und den Code schreiben, um die Anmeldeanforderung zu verarbeiten, wie unten gezeigt:
代码已经完成了,现在可以创建一些模板文件来呈现登录、二次验证和控制面板页面了。下面是示例模板文件,你可以根据自身需求对其进行修改。
gin.Default()
des Gin-Frameworks Erstellen Sie einen einfachen Router. Anschließend verwenden wir die Funktion sessions.NewCookieStore
, um einen Cookie-Store zum Speichern der Sitzung zu erstellen, der zum Speichern der Sitzungsinformationen des Benutzers verwendet wird. Wir haben Session-Middleware in der Router-Middleware verwendet und sie mysession
genannt. c.HTML
, um die Anmeldeseite darzustellen. Bei der Login-Route erhalten wir den vom Benutzer eingegebenen Benutzernamen und das Passwort und validieren sie dann in einer Funktion, die wir später implementieren. Wenn die Authentifizierung erfolgreich ist, speichern wir den Benutzernamen in der Sitzung und leiten den Benutzer zur zweiten Authentifizierungsseite weiter.
Als nächstes schreiben wir die Seite und Funktion für die zweite Authentifizierung. Hier überprüfen wir, ob wir uns über die Sitzung angemeldet haben. Wenn wir angemeldet sind, wird die sekundäre Authentifizierungsseite angezeigt und ein zufälliger 6-stelliger Bestätigungscode generiert. Der Bestätigungscode wird in der Sitzung gespeichert und per SMS, E-Mail oder Sicherheitstoken an den Benutzer gesendet.
<meta charset="UTF-8"> <title>Login</title>
Im obigen Code definieren wir eine Middleware mit dem Namen AuthRequired
, um zu prüfen, ob in der Sitzung ein angemeldeter Benutzer vorhanden ist. Bei unserem zweiten Weg verwenden wir diese Middleware, um den Benutzer zur Anmeldeseite umzuleiten, wenn der angemeldete Benutzer in der Sitzung nicht gefunden wird.
generateCode
, um einen 6-stelligen Bestätigungscode zu generieren, und verwenden die Funktion sendCode
, um den Bestätigungscode an den Benutzer zu senden. In unserer tatsächlichen Anwendung kann dieser Bestätigungscode per SMS, E-Mail oder Sicherheitstoken gesendet werden.
Wir verwenden eine POST-Anfrage und das Token auf der zweiten Route, um zu überprüfen, ob der zweistufige Authentifizierungscode des Benutzers korrekt ist. Wenn der Authentifizierungscode korrekt ist, wird der Benutzer zur Control Panel-Seite weitergeleitet.
<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>
<meta charset="UTF-8"> <title>Second Factor Authentication</title>
<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>
<meta charset="UTF-8"> <title>Dashboard</title>
<h1>欢迎访问控制面板</h1>
现在,我们的Gin应用程序就已经完成了。它使用Session中间件实现了用户认证机制,并使用了二次认证功能来增强安全性。