前言
在本文中,我将介绍如何使用 Go 语言搭建一个包含用户注册、登录、登出功能的完整认证系统。该系统使用 SQLite 作为数据库,JWT 作为身份验证token,并实现了优雅关闭等特性。
技术栈
- Go 语言
- SQLite 数据库
- JWT (JSON Web Token)
- Gorilla Mux 路由
- Bcrypt 密码加密
系统功能
- 用户注册
- 用户登录
- 用户登出
- Token 认证中间件
- 数据库管理
- 密码加密
项目结构
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}"
安全特性
- 密码使用 bcrypt 加密存储
- JWT token 认证
- token 失效机制
- 防止重复注册
- 优雅关闭服务
总结
这个认证系统虽然简单,但包含了一个完整认证系统所需的基本功能。它可以作为更大项目的起点,根据需求进行扩展。例如:
- 添加邮箱验证
- 实现密码重置
- 添加角色权限
- 增加社交媒体登录
- 添加双因素认证