userkit 是一个可复用的 Go 用户系统库,module path 为:
github.com/eecopilot/userkit
它适合被业务项目 import 使用,提供注册、登录、JWT 鉴权、基础用户管理、PostgreSQL / SQLite 持久化、Gin / net/http 接入,以及最小可用 RBAC。
- 用户注册和登录,支持邮箱或用户名登录。
- bcrypt 密码哈希。
- JWT Bearer Token 签发和校验。
- PostgreSQL 和 SQLite 两种 repository 实现,可自由选择。
- 基础用户管理:查询、列表、更新资料、启用/禁用、重置密码。
- 最小可用 RBAC:角色、权限、角色分配、动态角色和权限配置。
- Gin adapter 和标准库
net/httpadapter。 - 数据库迁移 SQL 和 consumer demo。
- Session Cookie。
- 邮箱验证和找回密码。
- refresh token 和 token 吊销。
- 审计日志。
- 多租户。
- MySQL 或 Redis repository。
go get github.com/eecopilot/userkit选择 PostgreSQL 时还需要 pgx driver:
go get github.com/jackc/pgx/v5SQLite 实现使用纯 Go 的 modernc.org/sqlite,随 userkit/sqlite 依赖自动安装,不需要 CGO 或系统 SQLite 开发库。
如果使用 Gin adapter:
go get github.com/gin-gonic/gin启动应用前依次执行:
migrations/001_create_users.sql
migrations/002_add_rbac.sql
本地开发可以直接启动仓库内 PostgreSQL:
cp .env.example .env
docker compose up -d postgres推荐使用 sqlite.Open。它会创建数据库文件、启用外键约束、WAL 和 5 秒 busy timeout,并自动执行内嵌迁移,不需要手工运行 SQL:
db, err := sqlite.Open(context.Background(), "./userkit.db")
if err != nil {
log.Fatal(err)
}
defer db.Close()
repo := sqlite.New(db)如果数据库连接由接入项目自行创建,需要先调用 sqlite.Migrate(ctx, db),再传给 sqlite.New(db)。
以下示例使用 SQLite,复制后即可运行:
package main
import (
"context"
"log"
"github.com/eecopilot/userkit"
"github.com/eecopilot/userkit/ginadapter"
"github.com/eecopilot/userkit/sqlite"
)
func main() {
db, err := sqlite.Open(context.Background(), "./userkit.db")
if err != nil {
log.Fatal(err)
}
defer db.Close()
svc, err := userkit.NewService(sqlite.New(db), userkit.Config{
JWTSecret: "change-me-to-a-long-random-secret",
JWTIssuer: "my-app",
JWTAudience: "my-app-users",
})
if err != nil {
log.Fatal(err)
}
router := ginadapter.New(svc).Routes()
log.Fatal(router.Run(":8080"))
}使用 PostgreSQL 时,将数据库初始化替换为:
db, err := sql.Open("pgx", "postgres://user:pass@localhost:5432/app?sslmode=disable")
if err != nil {
log.Fatal(err)
}
defer db.Close()
repo := postgres.New(db)后续使用 userkit.NewService(repo, config),替代 SQLite 示例中的 userkit.NewService(sqlite.New(db), config)。同时导入 database/sql、github.com/eecopilot/userkit/postgres 和 _ "github.com/jackc/pgx/v5/stdlib"。PostgreSQL 需要在启动前手工完成迁移。
如果项目已有 Gin engine:
router := gin.Default()
ginadapter.New(svc).RegisterRoutes(router.Group("/api"))| 方法 | 路径 | 说明 |
|---|---|---|
POST |
/auth/register |
注册并返回 token。 |
POST |
/auth/login |
登录并返回 token。 |
GET |
/me |
获取当前用户。 |
POST |
/me/change-password |
当前用户修改自己的密码。 |
GET |
/users |
分页列出用户,需要 user:list。 |
GET |
/users/{id} |
查询用户,需要 user:read 或本人访问。 |
GET |
/users/{id}/permissions |
查询用户当前权限。 |
PATCH |
/users/{id} |
更新用户资料。 |
POST |
/users/{id}/enable |
启用用户。 |
POST |
/users/{id}/disable |
禁用用户。 |
POST |
/users/{id}/reset-password |
重置密码。 |
GET |
/permissions |
查询权限字典,需要 role:assign。 |
GET |
/roles |
查询角色列表,需要 role:assign。 |
POST |
/roles |
创建角色。 |
POST |
/roles/{role}/permissions |
给角色增加权限。 |
DELETE |
/roles/{role}/permissions/{permission} |
移除角色权限。 |
POST |
/users/{id}/roles |
给用户分配角色。 |
DELETE |
/users/{id}/roles/{role} |
移除用户角色。 |
默认角色:
super_adminuser_adminvieweruser
新注册用户默认拥有 user 角色。角色和权限可以通过 HTTP API 动态管理。
自定义角色名使用小写字母、数字、下划线或短横线;自定义权限名使用冒号分隔的小写动作段,例如 report:view。
详细设计见 docs/rbac.md。
完整 consumer demo 位于:
examples/rbacdemo
使用 SQLite 启动,无需预先创建数据库或执行迁移:
go run ./examples/rbacdemo/server \
-driver sqlite \
-sqlite-path './userkit.db' \
-jwt-secret 'change-me-to-a-long-random-secret' \
-jwt-issuer 'rbac-demo' \
-addr ':8080'使用 PostgreSQL 启动:
go run ./examples/rbacdemo/server \
-driver postgres \
-database-url 'postgres://userkit:userkit@localhost:55432/userkit_test?sslmode=disable' \
-jwt-secret 'change-me-to-a-long-random-secret' \
-jwt-issuer 'rbac-demo' \
-addr ':8080'go test ./...只验证 SQLite repository:
go test -count=1 ./sqlite集成测试:
set -a
. ./.env
set +a
go test ./... -tags=integration