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":"[email protected]","password":"123456"}'

2. 用户登录

bash 复制代码
curl -X POST http://localhost:8080/login \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","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. 优雅关闭服务

总结

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

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

参考资料

相关推荐
Emma歌小白1 分钟前
循环动态地创建多个不同的 DataFrame
后端·python
java1234_小锋4 分钟前
什么是Lua模块?你会如何使用NGINX的Lua模块来定制请求处理流程?
开发语言·nginx·lua
阿里云腾讯云谷歌云AWS代理商_小赵11 分钟前
腾讯云国际站:怎样部署TensorFlow深度学习模型?
后端
编程乐趣20 分钟前
一个简单又好用的.Net版本.env文件读写操作库
后端
web守墓人21 分钟前
【go语言】window环境从源码编译go
开发语言·后端·golang
学习OK呀24 分钟前
日常代码中加解密技术的使用
java·后端
木昜先生31 分钟前
知识点:深入理解 Java 虚拟线程(Project Loom)
java·后端
SimonKing34 分钟前
白嫖!开源Java图片验证码框架加固业务安全
java·后端·架构
悠然小熠34 分钟前
CentOS 7 的默认YUM源更换为国内的镜像源
后端
dongfeng369235 分钟前
高性能服务-Redis篇
后端