Skip to content

Repository files navigation

userkit

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/http adapter。
  • 数据库迁移 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/v5

SQLite 实现使用纯 Go 的 modernc.org/sqlite,随 userkit/sqlite 依赖自动安装,不需要 CGO 或系统 SQLite 开发库。

如果使用 Gin adapter:

go get github.com/gin-gonic/gin

数据库迁移

PostgreSQL

启动应用前依次执行:

migrations/001_create_users.sql
migrations/002_add_rbac.sql

本地开发可以直接启动仓库内 PostgreSQL:

cp .env.example .env
docker compose up -d postgres

SQLite

推荐使用 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/sqlgithub.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} 移除用户角色。

RBAC

默认角色:

  • super_admin
  • user_admin
  • viewer
  • user

新注册用户默认拥有 user 角色。角色和权限可以通过 HTTP API 动态管理。

自定义角色名使用小写字母、数字、下划线或短横线;自定义权限名使用冒号分隔的小写动作段,例如 report:view

详细设计见 docs/rbac.md

Demo

完整 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

文档

About

userkit

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages