构建 API 接口和用户认证的实践指南 | 青训营

43 阅读2分钟

API,即应用程序接口,是你的服务与外界交流的窗口。它就像是你服务的门卫,决定了谁可以进来,以及他们可以做什么。通过API接口,用户可以请求数据、提交信息、执行操作等。

一、项目结构规划

首先,我们需要规划项目的整体结构。一个典型的Go Web项目结构可能如下:

/api
    /v1
        user.go
    /v2
        user.go
/models
    user.go
/utils
    crypto.go
    database.go
main.go

在这个例子中,我们有一个api目录,其中包含了不同版本的API接口。在v1v2目录中,都有user.go文件,用于处理与用户相关的API接口。在models目录中,存放了与数据模型相关的代码,而在utils目录中,存放了一些辅助函数和工具类。

二、API接口设计

在Go中,我们可以使用标准库的net/http包来创建HTTP服务器和处理HTTP请求。以下是一个简单的API接口示例:

func handleGetUser(w http.ResponseWriter, r *http.Request) {
    // 获取用户ID
    id := r.URL.Query().Get("id")
    // 调用模型层获取用户信息
    user, err := models.GetUser(id)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    // 将用户信息转换为JSON格式并返回
    json.NewEncoder(w).Encode(user)
}

在这个例子中,我们定义了一个处理GET请求的handleGetUser函数。该函数从URL中获取用户ID,然后调用模型层的GetUser函数获取用户信息。最后,我们将用户信息转换为JSON格式并返回给客户端。

三、用户认证

为了实现用户认证,我们可以使用JWT(JSON Web Tokens)来生成和验证用户令牌。以下是一个使用Go标准库中的crypto/hmaccrypto/sha256来实现JWT签名的示例:

func generateToken(user *models.User) (string, error) {
    // 生成随机字符串作为密钥
    key := make([]byte, 32)
    if _, err := rand.Read(key); err != nil {
        return "", err
    }
    // 将用户信息转换为JSON格式
    payload := make(map[string]interface{})
    payload["id"] = user.Id
    payload["username"] = user.Username
    payload["exp"] = time.Now().Add(time.Hour * 72).Unix() // 设置令牌过期时间为72小时后
    // 对payload进行Base64编码并拼接密钥和payload字符串,生成token字符串
    token := jose.NewSignedJWT(payload, &jose.Signer{
        Algorithm: jose.HS256,
        Key:       key,
    })
    tokenString, err := token.CompactSerialize()
    if err != nil {
        return "", err
    }
    return tokenString, nil
}

在这个例子中,我们使用rand.Read函数生成了一个随机的32字节密钥,然后根据用户信息生成了JWT的payload。最后,我们使用jose.NewSignedJWT函数和密钥对payload进行签名,然后使用token.CompactSerialize函数将生成的token字符串返回给客户端。