如何将我的服务开放给用户:构建 API 接口和用户认证的实践指南 | 青训营

52 阅读3分钟

准备工作

在开始之前,确保已经安装了 Go 和相关的开发工具。为安装请自行百度。

另外,需要在项目中引入 Gin 框架。可以使用以下命令安装 Gin:

go get -u github.com/gin-gonic/gin

创建基本的 API

首先,创建一个简单的 API,其中包含一个 GET 路由,用于获取欢迎信息。

package main

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

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

    r.GET("/welcome", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "Welcome!",
        })
    })

    r.Run(":8080")
}

运行这个程序,应该可以在浏览器或 API 工具中访问 http://localhost:8080/welcome 并获取到欢迎信息。

添加用户认证

安装依赖

为了实现用户认证,使用 github.com/golang-jwt/jwt/v5 库来处理 JSON Web Tokens(JWT)。可以使用以下命令安装它:

go get -u github.com/golang-jwt/jwt/v5

创建用户模型

首先,创建一个简单的用户模型来存储用户信息。

package main

type User struct {
    ID       uint   `json:"id"`
    Username string `json:"username"`
    Password string `json:"password"`
}

注册和登录路由

创建注册和登录的路由,用于用户的注册和登录操作。

package main

import (
    "github.com/gin-gonic/gin"
    "github.com/golang-jwt/jwt/v5"
    "net/http"
    "time"
)

var users []User
var jwtSecret = []byte("your-secret-key")

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

    r.POST("/register", register)
    r.POST("/login", login)

    r.Run(":8080")
}

func register(c *gin.Context) {
    var user User
    if err := c.ShouldBindJSON(&user); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }

    // 模拟数据自增字段。
    user.ID = uint(len(users) + 1)
    // 模拟数据库存储。
    users = append(users, user)

    c.JSON(http.StatusOK, gin.H{"message": "注册成功!"})
}

func login(c *gin.Context) {
    var loginData struct {
        Username string `json:"username"`
        Password string `json:"password"`
    }
    if err := c.ShouldBindJSON(&loginData); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }

    var user User
    for _, u := range users {
        if u.Username == loginData.Username && u.Password == loginData.Password {
            user = u
            break
        }
    }

    if user.ID == 0 {
        c.JSON(http.StatusUnauthorized, gin.H{"error": "账号或密码错误!"})
        return
    }

    token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
        "id": user.ID,
        "exp": time.Now().Add(time.Hour * 24).Unix(),
    })

    tokenString, err := token.SignedString(jwtSecret)
    if err != nil {
        // 生成token失败。
        c.JSON(http.StatusInternalServerError, gin.H{"error": "系统错误!"})
        return
    }

    c.JSON(http.StatusOK, gin.H{"token": tokenString})
}

生成和验证 JWT

在登录成功后,生成一个 JWT 并返回给客户端。这个 JWT 包含用户的 ID 信息,并在有效期内可用于后续请求的认证。

为了在 API 中验证 JWT,创建一个中间件函数。

package main

import (
    "github.com/gin-gonic/gin"
    "github.com/golang-jwt/jwt/v5"
    "net/http"
    "strings"
)

func authMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {
        tokenString := c.GetHeader("Authorization")
        if authHeader == "" {
            c.JSON(http.StatusUnauthorized, gin.H{"error": "先登录吧~"})
            c.Abort()
            return
        }

        token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
            return jwtSecret, nil
        })

        if err != nil || !token.Valid {
            // 无效的token
            c.JSON(http.StatusUnauthorized, gin.H{"error": "先登录吧"})
            c.Abort()
            return
        }

        c.Next()
    }
}

保护 API 路由

现在,可以使用 authMiddleware 中间件来保护需要认证的 API 路由。

func main() {
    // ...

    api := r.Group("/api")
    api.Use(authMiddleware())
    {
        api.GET("/protected", func(c *gin.Context) {
            c.JSON(http.StatusOK, gin.H{"message": "这个接口需要先登录!"})
        })
    }

    r.Run(":8080")
}

现在,只有在提供有效 JWT 的情况下才能访问 /api/protected 路由。

总结

本文提供了使用 Gin 框架构建 API 接口和用户认证系统的实践指南。主要内容有:

  1. 准备工作: 确保安装了 Go 编程语言和所需的开发工具,并通过命令行安装了 Gin 框架以及 JSON Web Token(JWT)库。

  2. 创建基本的 API: 使用 Gin 创建了一个简单的 API,其中包含一个用于获取欢迎信息的 GET 路由。

  3. 添加用户认证:

    • 安装依赖:安装了 jwt-go 库,用于处理 JSON Web Tokens。
    • 创建用户模型:定义了一个简单的用户模型来存储用户信息。
    • 注册和登录路由:实现了用户注册和登录的路由,模拟了用户数据的存储和验证,并生成 JWT 返回给用户。
  4. 保护 API 路由: 创建了一个中间件函数用于验证 JWT,然后使用这个中间件来保护需要认证的 API 路由。

当然,这只是一个入门级的教程,实际应用中还有更多的细节和安全性措施需要考虑,比如密码加密、数据库集成等。希望这个指南能帮助你起步,了解如何在 Gin 中构建 API 和用户认证系统。