Golang权限管理系统

最近在学习用Golang开发权限管理系统,但遇到几个问题想请教大家:

  1. 如何设计RBAC模型的数据库表结构比较合理?
  2. Golang中有哪些适合做权限控制的中间件推荐?
  3. 对于API级别的细粒度权限控制有什么好的实现方案?
  4. 大家在实际项目中是怎么处理权限缓存和性能优化的?

希望能得到有相关经验的朋友指点,谢谢!

2 回复

推荐使用Casbin库,实现RBAC权限模型。通过定义策略文件,管理用户角色和资源权限。结合Gin框架,中间件验证请求权限,简洁高效。

更多关于Golang权限管理系统的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang 权限管理系统

核心设计思路

基于角色的访问控制(RBAC)模型,使用 Go 语言构建高性能的权限管理系统。

主要功能模块

  1. 用户管理 - 用户注册、登录、信息管理
  2. 角色管理 - 角色创建、分配、权限配置
  3. 权限管理 - 权限点定义、分配、验证
  4. 资源管理 - 受保护资源的权限控制

核心代码示例

1. 数据结构定义

package models

import "time"

type User struct {
    ID        uint      `gorm:"primaryKey"`
    Username  string    `gorm:"uniqueIndex;size:50"`
    Password  string    `gorm:"size:255"`
    Email     string    `gorm:"size:100"`
    Roles     []Role    `gorm:"many2many:user_roles;"`
    CreatedAt time.Time
    UpdatedAt time.Time
}

type Role struct {
    ID          uint   `gorm:"primaryKey"`
    Name        string `gorm:"uniqueIndex;size:50"`
    Description string `gorm:"size:200"`
    Permissions []Permission `gorm:"many2many:role_permissions;"`
}

type Permission struct {
    ID          uint   `gorm:"primaryKey"`
    Name        string `gorm:"uniqueIndex;size:100"`
    Description string `gorm:"size:200"`
    Resource    string `gorm:"size:50"`
    Action      string `gorm:"size:20"` // create, read, update, delete
}

2. 权限验证中间件

package middleware

import (
    "net/http"
    "your-app/models"
    "your-app/services"
)

func AuthMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        token := r.Header.Get("Authorization")
        if token == "" {
            http.Error(w, "Unauthorized", http.StatusUnauthorized)
            return
        }
        
        user, err := services.VerifyToken(token)
        if err != nil {
            http.Error(w, "Invalid token", http.StatusUnauthorized)
            return
        }
        
        ctx := context.WithValue(r.Context(), "user", user)
        next.ServeHTTP(w, r.WithContext(ctx))
    })
}

func PermissionMiddleware(resource, action string) func(http.Handler) http.Handler {
    return func(next http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            user := r.Context().Value("user").(*models.User)
            
            hasPermission := services.CheckPermission(user, resource, action)
            if !hasPermission {
                http.Error(w, "Forbidden", http.StatusForbidden)
                return
            }
            
            next.ServeHTTP(w, r)
        })
    }
}

3. 权限服务

package services

import (
    "your-app/models"
    "gorm.io/gorm"
)

func CheckPermission(user *models.User, resource string, action string) bool {
    var count int64
    db.Model(&models.Permission{}).
        Joins("JOIN role_permissions ON role_permissions.permission_id = permissions.id").
        Joins("JOIN roles ON roles.id = role_permissions.role_id").
        Joins("JOIN user_roles ON user_roles.role_id = roles.id").
        Where("user_roles.user_id = ? AND permissions.resource = ? AND permissions.action = ?", 
              user.ID, resource, action).
        Count(&count)
    
    return count > 0
}

func GetUserPermissions(userID uint) ([]string, error) {
    var permissions []string
    err := db.Model(&models.Permission{}).
        Select("CONCAT(permissions.resource, ':', permissions.action)").
        Joins("JOIN role_permissions ON role_permissions.permission_id = permissions.id").
        Joins("JOIN roles ON roles.id = role_permissions.role_id").
        Joins("JOIN user_roles ON user_roles.role_id = roles.id").
        Where("user_roles.user_id = ?", userID).
        Pluck("CONCAT(permissions.resource, ':', permissions.action)", &permissions).Error
    
    return permissions, err
}

4. 路由配置示例

package routes

import (
    "your-app/controllers"
    "your-app/middleware"
)

func SetupRoutes(r *mux.Router) {
    // 公开路由
    r.HandleFunc("/login", controllers.Login).Methods("POST")
    r.HandleFunc("/register", controllers.Register).Methods("POST")
    
    // 需要认证的路由
    authRouter := r.PathPrefix("/api").Subrouter()
    authRouter.Use(middleware.AuthMiddleware)
    
    // 用户管理(需要用户读取权限)
    authRouter.HandleFunc("/users", controllers.GetUsers).Methods("GET").
        Use(middleware.PermissionMiddleware("user", "read"))
    
    // 用户创建(需要用户创建权限)
    authRouter.HandleFunc("/users", controllers.CreateUser).Methods("POST").
        Use(middleware.PermissionMiddleware("user", "create"))
}

技术栈建议

  • Web框架: Gin 或 Echo
  • 数据库: PostgreSQL/MySQL
  • ORM: GORM
  • 认证: JWT
  • 缓存: Redis(用于权限缓存)

扩展建议

  1. 添加权限缓存提升性能
  2. 实现细粒度的数据权限控制
  3. 添加操作日志记录
  4. 支持多租户架构
  5. 提供管理界面

这个系统提供了基础的RBAC权限管理功能,可以根据具体业务需求进行扩展和优化。

回到顶部