auth

package
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 13, 2026 License: MIT Imports: 11 Imported by: 0

README

Auth 组件

Auth 组件为 Genesis 框架提供统一的认证能力,基于 JWT (JSON Web Token) 实现。

特性

  • 安全性保障
    • 严格的签名方法验证(仅支持 HS256)
    • Claims 不可变性(GenerateToken 不会修改原始 Claims)
    • 完善的刷新令牌验证(Issuer、Audience、时间窗口检查)
  • 无状态认证:JWT 自包含用户信息,易于横向扩展。
  • 多源 Token 提取:自动从 Header、Query、Cookie 中提取 Token,开箱即用。
  • Gin 集成:提供开箱即用的中间件。
  • 遵循 L0 规范:集成 clogmetricsxerrors
  • 标准协议:使用 github.com/golang-jwt/jwt/v5 标准库。

目录结构

auth/
├── auth.go         # 接口定义 + 实现
├── config.go       # 配置结构
├── errors.go       # 哨兵错误
├── options.go      # 函数式选项
├── claims.go       # Claims 定义
├── metrics.go      # 指标常量
└── middleware.go   # Gin 中间件

核心接口

Authenticator
type Authenticator interface {
    // GenerateToken 生成 Token
    GenerateToken(ctx context.Context, claims *Claims) (string, error)

    // ValidateToken 验证 Token,返回 Claims
    ValidateToken(ctx context.Context, token string) (*Claims, error)

    // RefreshToken 刷新 Token
    RefreshToken(ctx context.Context, token string) (string, error)

    // GinMiddleware 返回 Gin 认证中间件
    GinMiddleware() gin.HandlerFunc
}
Claims
type Claims struct {
    // 标准声明 (使用 jwt.RegisteredClaims)
    jwt.RegisteredClaims

    // 自定义声明
    Username string         `json:"uname,omitempty"`
    Roles    []string       `json:"roles,omitempty"`
    Extra    map[string]any `json:"extra,omitempty"`
}

配置

auth:
    secret_key: "your-secret-key-min-32-chars-long"
    signing_method: "HS256"
    issuer: "my-service"
    access_token_ttl: 15m
    refresh_token_ttl: 168h
    # token_lookup: 可选,留空则使用默认多源查找
    # 默认查找顺序: header:Authorization -> query:token -> cookie:jwt
    token_lookup: "header:Authorization" # 可指定单一来源
    token_head_name: "Bearer"
Token 提取方式

默认情况下(token_lookup 留空),组件会按以下顺序尝试提取 Token:

  1. Header: Authorization: Bearer <token>
  2. Query: ?token=<token>
  3. Cookie: jwt=<token>

这种设计使得同一份配置可以同时支持:

  • REST API(使用 Header)
  • WebSocket 连接(使用 Query)
  • 前端应用(使用 Cookie)

如果需要限制只从特定来源提取,可配置 token_lookup

&auth.Config{
    SecretKey: "...",
    TokenLookup: "query:token",  // 只从 query 提取
}

使用示例

初始化
// 创建认证器
authenticator, err := auth.New(&auth.Config{
    SecretKey: "your-secret-key-at-least-32-chars",
}, auth.WithLogger(logger))
登录并生成 Token
claims := &auth.Claims{
    RegisteredClaims: jwt.RegisteredClaims{
        Subject: user.ID,
    },
    Username: user.Username,
    Roles:    []string{"admin"},
}

token, err := authenticator.GenerateToken(ctx, claims)
在中间件中使用
r := gin.Default()
r.Use(authenticator.GinMiddleware())

// 需要认证的路由
r.GET("/profile", func(c *gin.Context) {
    claims, _ := auth.GetClaims(c)
    c.JSON(200, gin.H{"user_id": claims.Subject})
})

// 要求特定角色的路由(OR 逻辑)
r.GET("/admin", auth.RequireRoles("admin"), handler)
r.GET("/moderate", auth.RequireRoles("admin", "moderator"), handler)  // 拥有任一角色即可
RequireRoles

RequireRoles 是一个角色检查中间件,采用 OR 逻辑

  • 用户只需拥有 任意一个 指定角色即可通过
  • RequireRoles("admin", "editor") 表示用户必须有 admineditor 角色
  • 如果没有任何匹配角色,返回 403 Forbidden

监控指标

Auth 组件提供以下可观测性指标,业务方可通过导出的常量引用指标名称:

指标名 类型 标签 描述
auth_tokens_validated_total Counter status="success|error", error_type="expired|invalid_signature|invalid_token" Token 验证计数
auth_tokens_refreshed_total Counter status="success|error" Token 刷新计数
指标常量引用
import "github.com/ceyewan/genesis/auth"

// 使用导出的常量引用指标名
metricName := auth.MetricTokensValidated
Prometheus 查询示例
# 验证成功率
rate(auth_tokens_validated_total{status="success"}[5m]) / rate(auth_tokens_validated_total[5m])

# 验证失败数(按错误类型分组)
sum by (error_type) (rate(auth_tokens_validated_total{status="error"}[5m]))

# 刷新成功率
rate(auth_tokens_refreshed_total{status="success"}[5m]) / rate(auth_tokens_refreshed_total[5m])

# 刷新失败数
sum(rate(auth_tokens_refreshed_total{status="error"}[5m]))
指标说明
  • Token 缺失(客户端未提供 token)不计入验证失败指标
  • 验证失败 仅统计提供了 token 但验证失败的情况(过期、签名错误、格式错误)

Documentation

Overview

Package auth 提供基于 JWT 的认证能力。

遵循 Genesis L3 治理层规范,支持:

  • Token 生成、验证与刷新
  • Gin 中间件集成
  • 基于角色的访问控制 (RBAC)
  • 多种 Token 提取方式 (Header, Cookie, Query)

基本使用:

authenticator, _ := auth.New(&auth.Config{SecretKey: "..."})
token, _ := authenticator.GenerateToken(ctx, &auth.Claims{
    RegisteredClaims: jwt.RegisteredClaims{Subject: "user-123"},
})

Index

Constants

View Source
const (
	// MetricTokensValidated Token 验证计数,标签: status, error_type
	MetricTokensValidated = "auth_tokens_validated_total"

	// MetricTokensRefreshed Token 刷新计数,标签: status
	MetricTokensRefreshed = "auth_tokens_refreshed_total"
)
View Source
const ClaimsKey = "auth:claims"

Variables

View Source
var (
	ErrInvalidToken     = xerrors.New("auth: invalid token")
	ErrExpiredToken     = xerrors.New("auth: token expired")
	ErrMissingToken     = xerrors.New("auth: missing token")
	ErrInvalidClaims    = xerrors.New("auth: invalid claims")
	ErrInvalidSignature = xerrors.New("auth: invalid signature")
	ErrInvalidConfig    = xerrors.New("auth: invalid config")
)

Functions

func RequireRoles

func RequireRoles(roles ...string) gin.HandlerFunc

RequireRoles 要求用户拥有其中一个角色的中间件,采用 OR 逻辑 RequireRoles("admin", "editor") 表示用户必须拥有 admin 或 editor 角色之一

Types

type Authenticator

type Authenticator interface {
	// GenerateToken 生成 Token
	GenerateToken(ctx context.Context, claims *Claims) (string, error)

	// ValidateToken 验证 Token,返回 Claims
	ValidateToken(ctx context.Context, token string) (*Claims, error)

	// RefreshToken 刷新 Token
	RefreshToken(ctx context.Context, token string) (string, error)

	// GinMiddleware 返回 Gin 认证中间件
	GinMiddleware() gin.HandlerFunc
}

Authenticator 认证器接口

func New

func New(cfg *Config, opts ...Option) (Authenticator, error)

New 创建 Authenticator

type Claims

type Claims struct {
	// 标准声明 (包含 Subject, Issuer, ExpiresAt 等)
	jwt.RegisteredClaims

	// 业务扩展声明
	Username string         `json:"uname,omitempty"` // 用户名
	Roles    []string       `json:"roles,omitempty"` // 角色列表
	Extra    map[string]any `json:"extra,omitempty"` // 扩展信息
}

Claims 定义了 JWT 载荷结构。

它内嵌了 jwt.RegisteredClaims 以支持标准声明(如 exp, sub, iss 等), 同时扩展了 Genesis 框架常用的业务字段。

字段说明:

  • Username: 用户名 (对应 uname)
  • Roles: 角色列表 (对应 roles)
  • Extra: 扩展字段 (对应 extra)

func GetClaims

func GetClaims(c *gin.Context) (*Claims, bool)

GetClaims 从 Gin Context 获取 Claims

type Config

type Config struct {
	// JWT 配置
	SecretKey     string   `mapstructure:"secret_key"`     // 签名密钥(至少 32 字符)
	SigningMethod string   `mapstructure:"signing_method"` // 签名方法: HS256(目前只支持)
	Issuer        string   `mapstructure:"issuer"`         // 签发者
	Audience      []string `mapstructure:"audience"`       // 接收者

	// Token 有效期
	AccessTokenTTL  time.Duration `mapstructure:"access_token_ttl"`  // Access Token TTL,默认 15m
	RefreshTokenTTL time.Duration `mapstructure:"refresh_token_ttl"` // Refresh Token TTL,默认 7d

	// Token 提取配置(可选,覆盖默认查找顺序)
	// 默认顺序: header:Authorization -> query:token -> cookie:jwt
	// 可指定单一来源如 "header:Authorization" 或 "query:token"
	TokenLookup   string `mapstructure:"token_lookup"`    // 提取方式,留空使用默认多源查找
	TokenHeadName string `mapstructure:"token_head_name"` // Header 前缀,默认 Bearer
}

Config Auth 配置

type Option

type Option func(*options)

Option 配置选项函数

func WithLogger

func WithLogger(l clog.Logger) Option

WithLogger 注入日志记录器,自动添加 "auth" 命名空间

func WithMeter

func WithMeter(m metrics.Meter) Option

WithMeter 注入指标 Meter

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL