服务端相关 / 47 使用 gin 包优化登录功能

上一个实战文章我们学习了如何使用 Go 语言原生的 http 包来构建一个 web 应用,实现了一个简单的登录功能。因为原生的 http 包很多功能都需要自己去写,所以就有很多开发者在原生包的基础上开发了第三方包。本文就来介绍一个开发 Go web 十分流行的包—— gin 包。其官方地址为:https://github.com/gin-gonic/gin

1. 下载 gin 包

因为是第三方包,所以需要从 github 上下载后才可使用。使用以下指令下载使用:

go get https://github.com/gin-gonic/gin

可能会比较久,如果觉得下载不便的话,可以直接使用 go mod 来构建项目,就可以跳过下载这个步骤。

2. 搭建服务

本文将使用 go mod 来构建项目,所以先在一个空白项目中执行

go mod init

然后再在 Go 文件写入以下代码构建 web 服务,代码示例:

package main

import (
    "github.com/gin-gonic/gin"//导入gin包
)

func main() {
    router := gin.Default()//实例化一个gin
    router.Run("127.0.0.1:9300")//监听9300端口
}

启动述代码就可以启动一个 gin 的 web 服务,此时会打印一些 gin 的日志,表示服务已启动。

Tips:如果你事前没有gin包,gomod会帮你自动下载。

图片描述

此时在在浏览器中输入127.0.0.1:9300/index。会报出404,于此同时,控制台中会打印相关错误,这个功能也是我很喜欢的一个功能。

图片描述

3. 编写路由

服务已经启动了,接下来看看如何创建 gin 的路由。和前文一样,我们先来创建一个处理 GET 请求的路由/index

代码示例:

package main

import (
    "net/http"

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

func main() {
    router := gin.Default()
    //创建get请求
    router.GET("/index", func(c *gin.Context) {
        c.String(http.StatusOK, "<h1>Hello Codey!</h1>")
    })
    router.Run("127.0.0.1:9300")
}

执行上述代码之后,在浏览器中输入127.0.0.1:9300/index

你会发现**<h1>这个标签没有被浏览器识别,而是以字符串的形式输出了**。

图片描述

这是因为 gin 框架中对输出做出了严格的分类,在 c.String() 函数中输出的值只会是字符串的形式输出,这是在原生函数之上为了**防止XSS(****跨站脚本攻击)**而做的优化。所以它无法直接打印 html 脚本来渲染页面,必须要使用 c.HTML() 函数来加载 html 文件。

代码示例:

package main

import (
    "net/http"

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

func main() {
    router := gin.Default()
    router.LoadHTMLGlob("view/*")//设定html存放的文件目录
    router.GET("/index", func(c *gin.Context) {
        c.HTML(http.StatusOK, "index.html", nil)//打开view.index.html
    })
    router.Run("127.0.0.1:9300")
}

目录结构如下

图片描述

index.html 代码如下:

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Go语言实战2</title>
</head>
<body>
    <div>
        <h3>登录</h3>
        <form action="check" method="POST">
            <div>
                <div>
                    <input type="text"  id="username" name="username" placeholder="请输入账号">
                </div>
            </div>
            <div>
                <div>
                    <input type="password" class="form-control" id="password" name="password" placeholder="请输入密码">
                </div>
            </div>
            <div >
                <div >
                    <button id="loginbtn" type="submit" >登录</button>
                </div>
            </div>
        </form>
    </div>
</body>
</html>

执行上述代码之后,在浏览器中输入127.0.0.1:9300/index

图片描述

此处可以结合函数式编程的思想,将 index 的处理函数拿出来作为一个变量,代码修改后如下所示:

package main

import (
    "net/http"

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

func main() {
    router := gin.Default()
    router.LoadHTMLGlob("view/*")
    router.GET("/index", index)
    router.Run("127.0.0.1:9300")
}

func index(c *gin.Context) {
    c.HTML(http.StatusOK, "index.html", nil)
}

4. 数据传输

然后我们就用 gin 来写一个 post 服务 check 用来接收验证登录页面发送过来的账号密码。

代码示例:

package main

import (
    "fmt"
    "net/http"

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

func main() {
    router := gin.Default()
    router.LoadHTMLGlob("view/*")
    router.GET("/index", index)
    router.POST("/check", check)
    router.Run("127.0.0.1:9300")
}

func index(c *gin.Context) {
    c.HTML(http.StatusOK, "index.html", nil)
}

func check(c *gin.Context) {
    accountID, _ := c.GetPostForm("username")
    password, _ := c.GetPostForm("password")
    fmt.Println(accountID, password)
    if accountID == "Codey" && password == "12345" {
        //跳转到主页
        c.HTML(http.StatusOK, "home.html", nil)
    } else {
        //跳转到登录
        c.Writer.Write([]byte("<script>alert('账号或者密码不正确')</script>"))
        c.HTML(http.StatusOK, "index.html", nil)
    }

}

home.html 代码如下:

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Go语言实战2</title>
</head>
<body>
    <div>
        <h3>主页</h3>
       这里是主页
    </div>
</body>
</html>

执行上述 Go 语言代码,在浏览器中输入127.0.0.1:9300/index

图片描述

输入正确的账号:Codey,密码:12345

图片描述
然后点击登录,会跳转到主页

图片描述

若输入错误的账号密码,则不跳转

图片描述

随后跳转回登录页面

图片描述

在 gin 中一个简易的登录功能就搭建完成了。

5. 小结

本文主要使用了gin这个第三方开发包,来搭建了一个Go语言的web应用,这个gin包的本质还是http包,但是它在其上封装了一层接口,使我们可以更高效的开发以及开发出来的应用更安全。在我们Go语言的学习和开发的过程中,在熟悉了官方库之后,我们也可以去使用一些能更好的帮助我们开发的第三方包。