Go语言实战:快速搭建完整的用户认证系统

前言

在本文中,我将介绍如何使用 Go 语言搭建一个包含用户注册、登录、登出功能的完整认证系统。该系统使用 SQLite 作为数据库,JWT 作为身份验证token,并实现了优雅关闭等特性。

技术栈

  • Go 语言
  • SQLite 数据库
  • JWT (JSON Web Token)
  • Gorilla Mux 路由
  • Bcrypt 密码加密

系统功能

  1. 用户注册
  2. 用户登录
  3. 用户登出
  4. Token 认证中间件
  5. 数据库管理
  6. 密码加密

项目结构

Main/

├── db.go // 数据库初始化和配置

├── main.go // 主程序入口

├── middleware.go // 认证中间件

├── handlers.go // HTTP处理器

├── model.go // 数据模型

└── utils.go // 工具函数

详细实现

1. 数据库设计

在 db.go 中,我们使用 SQLite 创建了两个主要表:

  • users:存储用户信息
  • tokens:存储用户的认证令牌
Go 复制代码
CREATE TABLE IF NOT EXISTS users (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    email TEXT NOT NULL UNIQUE,
    password TEXT NOT NULL,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    name TEXT,
    age INTEGER
);

CREATE TABLE IF NOT EXISTS tokens (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    user_id INTEGER NOT NULL,
    token TEXT NOT NULL,
    expired_at DATETIME NOT NULL,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    is_revoked BOOLEAN DEFAULT FALSE,
    FOREIGN KEY (user_id) REFERENCES users(id)
);

2. 数据模型

在 model.go 中定义了系统需要的各种数据结构:

Go 复制代码
type User struct {
    ID        int       `json:"id"`
    Email     string    `json:"email"`
    Password  string    `json:"password,omitempty"`
    CreatedAt time.Time `json:"created_at"`
    UpdatedAt time.Time `json:"updated_at"`
    Name      string    `json:"name"`
    Age       int       `json:"age"`
}

type LoginRequest struct {
    Email    string `json:"email" validate:"required,email"`
    Password string `json:"password" validate:"required,min=6"`
}

type RegisterRequest struct {
    Email    string `json:"email" validate:"required,email"`
    Password string `json:"password" validate:"required,min=6"`
}

3. 认证中间件

在 middleware.go 中实现了 JWT token 验证中间件:

Go 复制代码
func AuthMiddleware(db *sql.DB) func(http.Handler) http.Handler {
    return func(next http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            // 验证 token
            authHeader := r.Header.Get("Authorization")
            tokenString := strings.TrimPrefix(authHeader, "Bearer ")
            // ... token 验证逻辑 ...
        })
    }
}

4. 主要处理函数

在 handlers.go 中实现了三个主要的处理函数:

注册处理
Go 复制代码
func RegisterHandler(db *sql.DB) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        // 1. 解析请求数据
        // 2. 验证邮箱是否已存在
        // 3. 加密密码
        // 4. 保存用户信息
    }
}
登录处理
Go 复制代码
func LoginHandler(db *sql.DB) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        // 1. 验证用户凭证
        // 2. 生成 JWT token
        // 3. 保存 token 记录
        // 4. 返回 token
    }
}
登出处理
Go 复制代码
func LogoutHandler(db *sql.DB) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        // 将 token 标记为已撤销
    }
}

5. 工具函数

在 utils.go 中实现了一些辅助功能:

  • 密码加密和验证
  • JWT token 生成
  • 其他辅助函数

6. 主程序

在 main.go 中设置路由并启动服务器:

Go 复制代码
func main() {
    // 初始化数据库
    db, err := initDB()
    
    // 设置路由
    r := mux.NewRouter()
    r.HandleFunc("/register", RegisterHandler(db)).Methods(http.MethodPost)
    r.HandleFunc("/login", LoginHandler(db)).Methods(http.MethodPost)
    
    // API 路由组
    api := r.PathPrefix("/api").Subrouter()
    api.Use(AuthMiddleware(db))
    api.HandleFunc("/logout", LogoutHandler(db)).Methods(http.MethodPost)
    
    // 启动服务器
    srv := &http.Server{
        Handler: r,
        Addr:    ":8080",
    }
    // ... 优雅关闭逻辑 ...
}

使用方法

1. 注册新用户

bash 复制代码
curl -X POST http://localhost:8080/register \
  -H "Content-Type: application/json" \
  -d '{"email":"user@example.com","password":"123456"}'

2. 用户登录

bash 复制代码
curl -X POST http://localhost:8080/login \
  -H "Content-Type: application/json" \
  -d '{"email":"user@example.com","password":"123456"}'

3. 用户登出

bash 复制代码
curl -X POST http://localhost:8080/api/logout \
  -H "Authorization: Bearer {your-token}"

安全特性

  1. 密码使用 bcrypt 加密存储
  2. JWT token 认证
  3. token 失效机制
  4. 防止重复注册
  5. 优雅关闭服务

总结

这个认证系统虽然简单,但包含了一个完整认证系统所需的基本功能。它可以作为更大项目的起点,根据需求进行扩展。例如:

  • 添加邮箱验证
  • 实现密码重置
  • 添加角色权限
  • 增加社交媒体登录
  • 添加双因素认证

参考资料

相关推荐
雪芽蓝域zzs9 分钟前
第十六节:递归组件实现无限层级折叠侧边栏菜单
开发语言·javascript·ecmascript
Casbin开源社区14 分钟前
一个面板管住 29 个 AI 编程 Agent:Casbin Gateway 的配置统一、协议互转、用量统计与权限管控
人工智能·golang·开源·gateway·casbin
神明不懂浪漫36 分钟前
【第二章】库、表、增删改查操作
开发语言·数据库·经验分享·笔记
传奇开心果编程37 分钟前
【Rust入门知识点学与练】第11课:HashMap 键值对集合
开发语言·学习·rust
yume_sibai1 小时前
03-Rust 函数式编程特性(闭包 + Iterator + Option/Result + 链式调用)
开发语言·后端·rust
奈斯先生Vector1 小时前
AIGC 视频生成实战:用 Kling Video 拆解文生视频、图生视频与完整工作流
开发语言·人工智能·windows·python·aigc·音视频
吃饱了得干活1 小时前
Redis 不是死脑筋,它是一套“会进化”的存储系统
redis·后端
伩仁1 小时前
别再 HTTP 200 一把梭了:用 RFC 9457 Problem Details 给 FastAPI 错误响应"立规矩"
后端
小玮看世界1 小时前
[Python]螺旋遍历 vs 最短路径:方向控制类算法的“同源异流”
开发语言·python·算法
MeetTanG1 小时前
Go 实战锦囊|errgroup:优雅地管理并发任务组
后端·go