GoWindGoWind
Home
Framework
GoWind Toolkit
  • Open Source

    • GoWind Admin (Admin Platform)
    • GoWind CMS (Content Management)
    • GoWind UBA (Behavior Analytics)
    • GoWind Shop (E-commerce)
    • GoWind Kanban (Kanban Boards)
    • GoWind Ledger (Personal Finance)
    • GoWind ShortPlay (Short Drama)
    • GoWind Ops (Operations Platform)
    • RushWind (Rust Ecosystem)
  • Open Core (Community + Enterprise)

    • GoWind OA (Office Collaboration)
    • GoWind ERP (Procure-to-Pay)
    • GoWind WMS (Warehousing)
  • Commercial

    • GoWind IM (Instant Messaging)
    • GoWind IoT (IoT Platform)
    • GoWind Edu (AI Education)
    • GoWind MES (Manufacturing Execution)
    • GoWind CDC (Data Pipeline)
    • GoWind SDP (Zero-Trust Gateway)
    • GoWind Quant (Quant Research)
    • GoWind Trade Radar (Export Sourcing)
    • GoWind Game Radar (Game Greenlight)
  • 简体中文
  • English
GitHub
Home
Framework
GoWind Toolkit
  • Open Source

    • GoWind Admin (Admin Platform)
    • GoWind CMS (Content Management)
    • GoWind UBA (Behavior Analytics)
    • GoWind Shop (E-commerce)
    • GoWind Kanban (Kanban Boards)
    • GoWind Ledger (Personal Finance)
    • GoWind ShortPlay (Short Drama)
    • GoWind Ops (Operations Platform)
    • RushWind (Rust Ecosystem)
  • Open Core (Community + Enterprise)

    • GoWind OA (Office Collaboration)
    • GoWind ERP (Procure-to-Pay)
    • GoWind WMS (Warehousing)
  • Commercial

    • GoWind IM (Instant Messaging)
    • GoWind IoT (IoT Platform)
    • GoWind Edu (AI Education)
    • GoWind MES (Manufacturing Execution)
    • GoWind CDC (Data Pipeline)
    • GoWind SDP (Zero-Trust Gateway)
    • GoWind Quant (Quant Research)
    • GoWind Trade Radar (Export Sourcing)
    • GoWind Game Radar (Game Greenlight)
  • 简体中文
  • English
GitHub
  • Introduction

    • GoWind CMS Product Introduction
    • GoWind CMS Installation Guide
  • Backend

    • CMS Backend Architecture Overview
    • CMS Backend Modules Overview
    • CMS Protobuf API Definitions
    • CMS Configuration and Deployment Guide
    • Backend Extension Mechanisms Guide
  • Frontend

    • CMS Frontend Architecture
    • CMS Frontend Modules Overview
  • Getting Started

    • Adding a Content Type, Full Stack in Practice
    • Multi-Client API Client Code Generation Tutorial
  • Core Tutorials

    • Content Multilingual Translation Tutorial
    • Content Publishing Workflow Tutorial
    • Section Editor in Practice
    • Headless API Multi-Client Integration in Practice
    • Frontend Application Development in Practice
  • Intermediate Tutorials

    • Multi-Site Management in Practice
    • Media Asset Management in Practice
    • Comment System Tutorial
    • Event Bus Architecture in Practice
    • Lua Script Extensions in Practice
  • Advanced Topics

    • Permission System in Practice
    • Dual-Client Login Security in Practice
    • Encryption and Security Toolkit Tutorial
    • Full-Text Search in Practice
    • Task Scheduling in Practice
    • Real-Time Message Push (SSE) in Practice
    • Performance Monitoring in Practice
    • Dictionary Management System Tutorial
  • Full-Stack Guides

    • Full-Stack Integration in Practice
    • Three-Service Deployment Tutorial

Permission System in Practice

GoWind CMS shares the same technical foundation as GoWind Admin (Casbin + JWT), but its permission model has a unique design due to the Headless dual-API architecture. This tutorial takes a deep dive into the CMS's dual front-/back-office permission model, the authentication whitelist, data isolation, and frontend permission control.

Prerequisites

  • You have read CMS Backend Architecture Overview
  • It is recommended to first read GoWind Admin Permission System Deep Dive

1. CMS Permission Architecture

1.1 Dual-API Permission Comparison

1.2 CMS vs. Admin Permission Differences

ComparisonGoWind AdminGoWind CMS
API layeringSingle Admin APIDual-layer Admin API + App API
User typesAdministratorsAdministrators + frontend users
Auth whitelistLogin endpoint onlyLogin + content browsing endpoints
Permission modelRBACRBAC (admin side) + whitelist (frontend)
Token typeadminadmin + app
Data isolationTenant isolationTenant isolation + public/private layering

2. Authentication System

2.1 Dual-Token Mechanism

// authentication/service/v1/types.proto
enum ClientType {
  CLIENT_TYPE_UNSPECIFIED = 0;
  CLIENT_TYPE_ADMIN = 1;   // 管理后台
  CLIENT_TYPE_APP = 2;     // 前台应用
}

The JWT token contains a clientType field that distinguishes where the token comes from:

{
  "user_id": 1,
  "tenant_id": 1,
  "roles": ["admin"],
  "client_type": "admin",
  "exp": 1735689600
}

2.2 Login Authentication Flow

Admin console login:

POST /admin/v1/login
{
  "username": "admin",
  "password": "xxx",
  "clientType": 1
}

Frontend application login:

POST /app/v1/login
{
  "username": "user@example.com",
  "password": "xxx"
}
# 后端自动设置 clientType=2

2.3 Token Validation Middleware

// pkg/middleware/auth.go
func Auth() middleware.Middleware {
    return func(handler middleware.Handler) middleware.Handler {
        return func(ctx context.Context, req interface{}) (interface{}, error) {
            if header, ok := transport.FromServerContext(ctx); ok {
                token := header.RequestHeader().Get("Authorization")
                token = strings.TrimPrefix(token, "Bearer ")

                claims, err := jwt.ParseToken(token)
                if err != nil {
                    return nil, errors.Unauthorized("TOKEN_INVALID", "token无效")
                }

                // 注入用户信息到 context
                ctx = context.WithValue(ctx, UserIDKey{}, claims.UserID)
                ctx = context.WithValue(ctx, TenantIDKey{}, claims.TenantID)
                ctx = context.WithValue(ctx, ClientTypeKey{}, claims.ClientType)
            }
            return handler(ctx, req)
        }
    }
}

3. Whitelist Mechanism

3.1 Admin Service Whitelist

The Admin API is strictly controlled; only the login endpoint is authentication-free:

// app/admin/service/internal/server/rest_server.go
rpc.AddWhiteList(
    adminV1.OperationAuthenticationServiceLogin,  // 只有登录接口免认证
)

3.2 App Service Whitelist

The App API whitelist is loose; all browsing endpoints are authentication-free:

// app/app/service/internal/server/rest_server.go
rpc.AddWhiteList(
    // 认证接口
    appV1.OperationAuthenticationServiceLogin,

    // 内容浏览(免登录,利于 SEO)
    appV1.OperationPostServiceList,
    appV1.OperationPostServiceGet,
    appV1.OperationCategoryServiceList,
    appV1.OperationCategoryServiceGet,
    appV1.OperationTagServiceList,
    appV1.OperationTagServiceGet,
    appV1.OperationPageServiceList,
    appV1.OperationPageServiceGet,
    appV1.OperationCommentServiceList,
    appV1.OperationCommentServiceGet,
    appV1.OperationNavigationServiceList,
)

3.3 Extending the Whitelist

When adding new frontend endpoints, they need to be added to the whitelist:

// 新增视频接口(免登录浏览)
rpc.AddWhiteList(
    appV1.OperationVideoServiceList,
    appV1.OperationVideoServiceGet,
)

4. RBAC Permission Model

4.1 Permission Hierarchy

4.2 Casbin Policies

The CMS uses the Casbin RBAC model, identical to Admin:

# model.conf
[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[role_definition]
g = _, _

[policy_effect]
e = some(where, p.eft == allow)

[matchers]
m = g(r.sub, p.sub) && keyMatch2(r.obj, p.obj) && (r.act == p.act || p.act == "*")

4.3 Admin Console Permission Checks

// app/admin/service/internal/server/rest_server.go
func NewRestServer(..., authorizer *authorizer.CasbinAuthorizer) *http.Server {
    srv := http.NewServer(...)

    // 中间件链
    srv.Use(
        middleware.Logging(),
        middleware.Audit(),
        authMiddleware,       // JWT 认证(跳过白名单)
        authzMiddleware(authorizer),  // Casbin 权限校验
    )

    return srv
}

5. Data Permissions

5.1 Tenant Data Isolation

Tenant filtering is automatically injected through the Ent Viewer mechanism:

// pkg/middleware/ent_viewer.go
func EntViewer() middleware.Middleware {
    return func(handler middleware.Handler) middleware.Handler {
        return func(ctx context.Context, req interface{}) (interface{}, error) {
            tenantId := ctx.Value(TenantIDKey{}).(uint32)

            // 注入租户上下文,Ent 会自动过滤
            ctx = context.WithValue(ctx, entgo.TenantKey{}, tenantId)
            return handler(ctx, req)
        }
    }
}

5.2 Department Data Scope

// 数据权限范围
enum DataScope {
  DATA_SCOPE_ALL = 0;        // 全部数据
  DATA_SCOPE_DEPT = 1;       // 本部门
  DATA_SCOPE_DEPT_AND_SUB = 2; // 本部门及子部门
  DATA_SCOPE_SELF = 3;       // 仅本人
}

6. Frontend Permission Control

6.1 Route Guards

Route-level permissions in the admin console (Vben Admin):

// frontend/admin/apps/admin/src/router/guard.ts
async function registerAccessGuard(router) {
  router.beforeEach(async (to, from, next) => {
    // 白名单路由
    if (WHITE_LIST.includes(to.path)) {
      next();
      return;
    }

    const token = getToken();
    if (!token) {
      next({ path: '/auth/login' });
      return;
    }

    // 检查路由权限
    const { hasAccessByRoles } = useAccess();
    if (!hasAccessByRoles(to.meta.authority)) {
      next({ path: '/403' });
      return;
    }

    next();
  });
}

6.2 Button-Level Permissions

<template>
  <!-- 有删除权限才显示按钮 -->
  <AccessControl :access="['post:delete']">
    <Button danger @click="handleDelete">删除</Button>
  </AccessControl>
</template>

6.3 Menu Permissions

Menus are rendered dynamically based on user roles:

// 根据权限过滤菜单
function filterMenusByPermission(menus: Menu[], permissions: string[]): Menu[] {
  return menus.filter((menu) => {
    if (menu.children) {
      menu.children = filterMenusByPermission(menu.children, permissions);
    }
    return !menu.permission || permissions.includes(menu.permission);
  });
}

7. Frontend User Permissions

7.1 Frontend vs. Backend Users

ComparisonAdmin Console UserFrontend User
Login endpoint/admin/v1/login/app/v1/login
Token typeadminapp
Permission modelCasbin RBACSimplified roles (regular user/VIP)
Accessible endpointsAll admin endpointsComments, posting, file upload

7.2 Frontend User Registration Flow

8. Checklist

Check ItemDescription
Dual-token mechanismadmin / app token distinction
Admin API whitelistLogin endpoint only
App API whitelistBrowsing endpoints are login-free
Casbin permission configurationRBAC model + policies
Tenant data isolationAutomatic filtering via Ent Viewer
Frontend route guardsLogin state + permission checks
Button-level permissionsAccessControl component
Frontend user registrationApp Service registration endpoint

Related Documents

  • CMS Backend Architecture Overview
  • GoWind Admin Permission System Deep Dive
  • GoWind Admin Login Security Tutorial
  • Headless API Multi-Client Integration in Practice
Edit this page
Last Updated:: 11/3/26, 2:14 PM
Contributors: Bobo
Next
Dual-Client Login Security in Practice