构建 Go 服务的 API 接口和用户认证 | 青训营

298 阅读3分钟

引言

在现代应用程序开发中,构建 API 接口和用户认证是非常常见的任务。本文将介绍如何使用 Go 语言构建一个简单的 API 服务,并实现用户认证。我们将通过一个示例项目,尝试学习如何创建 API 端点、处理用户身份验证以及保护需要身份验证的资源。

1. 创建一个基本的 Go 服务

首先,让我们创建一个基本的 Go 服务,它将作为我们的 API 服务的基础。

package main

import (
	"fmt"
	"net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintln(w, "欢迎访问 tuotuo-service API 服务")
}

func main() {
	http.HandleFunc("/", handler)
	fmt.Println("tuotuo-service 服务已启动,监听在 :8080 端口")
	http.ListenAndServe(":8080", nil)
}

以上代码创建了一个简单的 HTTP 服务,它在根路径 ("/") 下响应请求并返回一条欢迎消息。

2. 添加 API 端点

要构建一个真正的 API,我们需要添加一些端点(endpoints),每个端点对应一个不同的功能或资源。让我们添加一个 /api/users 端点来获取用户列表。

package main

import (
	"encoding/json"
	"fmt"
	"net/http"
)

type User struct {
	ID   int    `json:"id"`
	Name string `json:"name"`
}

var users = []User{
	{ID: 1, Name: "tuotuo"},
	{ID: 2, Name: "user1"},
	{ID: 3, Name: "user2"},
}

func getUsers(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(users)
}

func main() {
	http.HandleFunc("/api/users", getUsers)
	fmt.Println("tuotuo-service 服务已启动,监听在 :8080 端口")
	http.ListenAndServe(":8080", nil)
}

现在,我们有了一个 /api/users 端点,它返回一个包含用户信息的 JSON 响应。

3. 用户认证

为了保护一些敏感资源,我们需要添加用户认证。我们将使用基本身份验证(Basic Authentication)来实现这一目标。

package main

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"net/http"
	"strings"
)

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

var users = []User{
	{ID: 1, Username: "tuotuo", Password: "tuotuo-test"},
	{ID: 2, Username: "user1", Password: "pass123"},
	{ID: 3, Username: "user2", Password: "pass456"},
}

func getUsers(w http.ResponseWriter, r *http.Request) {
	authHeader := r.Header.Get("Authorization")
	if !strings.HasPrefix(authHeader, "Basic ") {
		w.WriteHeader(http.StatusUnauthorized)
		fmt.Fprintln(w, "需要身份验证")
		return
	}

	credsBase64 := strings.TrimPrefix(authHeader, "Basic ")
	credsBytes, err := base64.StdEncoding.DecodeString(credsBase64)
	if err != nil {
		w.WriteHeader(http.StatusUnauthorized)
		fmt.Fprintln(w, "无效的身份验证凭据")
		return
	}

	creds := string(credsBytes)
	usernamePassword := strings.SplitN(creds, ":", 2)
	if len(usernamePassword) != 2 {
		w.WriteHeader(http.StatusUnauthorized)
		fmt.Fprintln(w, "无效的身份验证凭据")
		return
	}

	username, password := usernamePassword[0], usernamePassword[1]
	authenticated := false
	for _, user := range users {
		if user.Username == username && user.Password == password {
			authenticated = true
			break
		}
	}

	if !authenticated {
		w.WriteHeader(http.StatusUnauthorized)
		fmt.Fprintln(w, "身份验证失败")
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(users)
}

func main() {
	http.HandleFunc("/api/users", getUsers)
	fmt.Println("tuotuo-service 服务已启动,监听在 :8080 端口")
	http.ListenAndServe(":8080", nil)
}

在上述代码中,我们通过检查请求头中的 Authorization 字段来进行身份验证。如果

请求不包含身份验证信息或信息无效,将返回 401 未授权响应。如果身份验证成功,将返回用户列表。

4. 示例程序输出

我们启动了上述程序并使用 cURL 进行测试。以下是一些示例命令和输出:

获取用户列表(未经身份验证):

$ curl http://localhost:8080/api/users
需要身份验证

获取用户列表(使用身份验证):

$ curl -u tuotuo:tuotuo-test http://localhost:8080/api/users
[{"id":1,"username":"tuotuo","password":"tuotuo-test"},{"id":2,"username":"user1","password":"pass123"},{"id":3,"username":"user2","password":"pass456"}]

获取用户列表(身份验证失败):

$ curl -u tuotuo:wrongpass http://localhost:8080/api/users
身份验证失败

结论

本文演示了如何使用 Go 语言构建一个简单的 API 服务,并添加用户认证功能。通过基本身份验证,我们能够保护 API 端点并限制访问敏感资源。这个示例项目可以作为起点,用于构建更复杂的 API 服务,提供更多功能和安全性。