Shopify Hydrogen RBAC ABAC Policy — จัดการสิทธิ์
RBAC ABAC Hydrogen

Shopify Hydrogen RBAC ABAC Policy Role-Based Attribute-Based Access Control Permission Middleware Authentication Authorization E-commerce Remix React
| Access Control | Based On | Flexibility | Complexity | เหมาะกับ |
|---|---|---|---|---|
| RBAC | Roles | ปานกลาง | ง่าย | ทั่วไป |
| ABAC | Attributes | สูงมาก | ซับซ้อน | Enterprise |
| ACL | User-Resource | ต่ำ | ง่าย | Simple Apps |
| ReBAC | Relationships | สูง | ปานกลาง | Social/Collab |
| PBAC | Policies | สูงมาก | สูง | Regulated |
RBAC Implementation
=== RBAC for Shopify Hydrogen ===
Remix Middleware — Role Check
app/middleware/auth.server.ts
import { redirect } from '@remix-run/node';
import { getSession } from '~/sessions.server';
export async function requireRole(request: Request, roles: string[]) {
const session = await getSession(request.headers.get('Cookie'));
const user = session.get('user');
if (!user) throw redirect('/login');
if (!roles.includes(user.role)) throw redirect('/unauthorized');
return user;
}
Usage in loader
export async function loader({ request }: LoaderFunctionArgs) {
const user = await requireRole(request, ['admin', 'editor']);
... fetch data
}
Role & Permission Schema
CREATE TABLE roles (
id SERIAL PRIMARY KEY,
name VARCHAR(50) UNIQUE NOT NULL,
description TEXT
);
CREATE TABLE permissions (
id SERIAL PRIMARY KEY,
resource VARCHAR(100) NOT NULL,
action VARCHAR(50) NOT NULL,
UNIQUE(resource, action)
);
CREATE TABLE role_permissions (
role_id INT REFERENCES roles(id),
permission_id INT REFERENCES permissions(id),
เนื้อหาเกี่ยวข้อง — แนะนำให้อ่าน inclusive แปลว่า — ทุกสิ่งที่ต้องรู้ในปี 2026
PRIMARY KEY (role_id, permission_id)
);
CREATE TABLE user_roles (
user_id INT REFERENCES users(id),
role_id INT REFERENCES roles(id),
PRIMARY KEY (user_id, role_id)
);
from dataclasses import dataclass
@dataclass
แนะนำเพิ่มเติม — อ่านเพิ่มเติมที่ SiamCafeBook
class RolePermission:
role: str
permissions: list
description: str
roles = [
RolePermission("super_admin", ["*:*"], "ทุกสิทธิ์ ทุก Resource"),
RolePermission("admin", ["products:*", "orders:*", "users:read", "analytics:read"], "จัดการสินค้า ออเดอร์ ดู User Analytics"),
RolePermission("editor", ["products:read", "products:write", "collections:*"], "จัดการสินค้า Collections"),
RolePermission("support", ["orders:read", "orders:update", "customers:read"], "ดูและอัพเดท Order ดู Customer"),
RolePermission("viewer", ["products:read", "orders:read", "analytics:read"], "ดูได้อย่างเดียว"),
RolePermission("customer", ["cart:*", "checkout:*", "orders:read:own"], "ซื้อสินค้า ดู Order ตัวเอง"),
]
print("=== RBAC Roles ===")
for r in roles:
print(f" [{r.role}] {r.description}")
print(f" Permissions: {', '.join(r.permissions)}")
ABAC Policy Engine
=== ABAC Policy Engine ===
Policy Definition
{
"id": "policy-001",
"description": "Regional manager sees orders in their region",
"effect": "allow",
"subjects": {"role": "regional_manager"},
"resources": {"type": "order"},
"actions": ["read", "update"],
"conditions": {
เนื้อหาเกี่ยวข้อง — บทความที่เกี่ยวข้อง: DNS over TLS Interview Preparation
"subject.region": {"equals": "resource.region"},
"environment.time": {"between": ["08:00", "18:00"]},
"environment.ip": {"in_cidr": "10.0.0.0/8"}
}
}
Python ABAC Engine
class PolicyEngine:
def __init__(self):
self.policies = []
def add_policy(self, policy):
self.policies.append(policy)
def evaluate(self, subject, resource, action, environment):
for policy in self.policies:
if self._match(policy, subject, resource, action, environment):

return policy['effect']
return 'deny' # Default deny
def _match(self, policy, subject, resource, action, environment):
if not self._match_subjects(policy.get('subjects', {}), subject):
return False
if not self._match_resources(policy.get('resources', {}), resource):
return False
if action not in policy.get('actions', []):
return False
if not self._match_conditions(policy.get('conditions', {}),
subject, resource, environment):
return False
return True
Casbin Integration
แนะนำเพิ่มเติม — ดูสัญญาณเทรดที่ XM Signal
pip install casbin
import casbin
# 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) && r.obj == p.obj && r.act == p.act
enforcer = casbin.Enforcer("model.conf", "policy.csv")
allowed = enforcer.enforce("alice", "products", "read")
เนื้อหาเกี่ยวข้อง — Java Virtual Threads Database Migration
@dataclass
class ABACPolicy:
name: str
subject_attr: str
resource_attr: str
condition: str
effect: str
use_case: str
policies = [
ABACPolicy("Regional Access", "role=manager, region=TH", "type=order, region=TH", "subject.region == resource.region", "Allow", "Manager เห็น Order ตาม Region"),
ABACPolicy("Business Hours", "role=staff", "type=report", "time between 08:00-18:00", "Allow", "Staff ดู Report เฉพาะเวลาทำงาน"),
ABACPolicy("Owner Only", "role=seller", "type=product, owner=seller_id", "subject.id == resource.owner", "Allow", "Seller เห็นเฉพาะสินค้าตัวเอง"),
ABACPolicy("VIP Discount", "tier=vip", "type=checkout", "subject.tier == 'vip'", "Apply 10% discount", "VIP ลด 10%"),
]
print("\n=== ABAC Policies ===")
for p in policies:
print(f" [{p.name}] Effect: {p.effect}")
print(f" Subject: {p.subject_attr}")
print(f" Resource: {p.resource_attr}")
print(f" Condition: {p.condition}")
print(f" Use Case: {p.use_case}")
Hydrogen Integration
=== Hydrogen Route Protection ===
app/routes/admin._index.tsx
import { requireRole } from '~/middleware/auth.server';
import { json } from '@remix-run/node';
export async function loader({ request }) {
const user = await requireRole(request, ['admin', 'super_admin']);
const stats = await fetchAdminStats();
return json({ user, stats });
}
app/routes/api.orders.$id.tsx
import { requirePermission } from '~/middleware/abac.server';
export async function loader({ request, params }) {
const user = await getUser(request);
const order = await getOrder(params.id);
เนื้อหาเกี่ยวข้อง — บทความที่เกี่ยวข้อง: python programming คือ
ABAC check: user can only see own orders or if admin
await requirePermission(user, order, 'read');
return json({ order });
}
app/middleware/abac.server.ts
export async function requirePermission(user, resource, action) {
const policies = await loadPolicies();
const engine = new PolicyEngine(policies);
const allowed = engine.evaluate(
{ id: user.id, role: user.role, region: user.region },
{ type: resource.type, owner: resource.ownerId, region: resource.region },
action,
{ time: new Date(), ip: request.headers.get('x-forwarded-for') }
);
if (!allowed) throw new Response('Forbidden', { status: 403 });
}
security_checklist = {
"Authentication": "Session Cookie + CSRF Token",
"RBAC Middleware": "requireRole() ทุก Admin Route",
"ABAC Engine": "Policy-based สำหรับ Fine-grained",
"API Protection": "JWT + Permission Check ทุก Endpoint",
"Input Validation": "Zod Schema Validation",
"Rate Limiting": "100 req/min per user",
"Audit Log": "บันทึกทุก Action ของ Admin",
"CORS": "Allow เฉพาะ Storefront Domain",
"CSP": "Content Security Policy Headers",
"Dependency Scan": "npm audit + Snyk weekly",
}
print("Security Checklist:")
for item, desc in security_checklist.items():
print(f" [{item}]: {desc}")
เคล็ดลับ
- RBAC First: เริ่มจาก RBAC ก่อน เพิ่ม ABAC เมื่อจำเป็น
- Least Privilege: ให้สิทธิ์น้อยที่สุดที่จำเป็น
- Audit: บันทึกทุก Access Decision สำหรับ Audit
- Middleware: ตรวจสอบสิทธิ์ที่ Middleware ไม่ใช่ใน Component
- Test: เขียน Test สำหรับทุก Policy ป้องกัน Regression
RBAC คืออะไร
Role-Based Access Control สิทธิ์ตาม Role Admin Editor Viewer Customer Permission กำหนด Role ให้ User จัดการง่าย Audit ตรวจสอบ





