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),
# 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
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": {
# "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
# 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")
@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);
#
# // 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 ตรวจสอบ
ABAC ต่างจาก RBAC อย่างไร
RBAC ใช้ Role ง่ายไม่ยืดหยุ่น ABAC ใช้ Attributes User Resource Environment Action Policy ซับซ้อน เช่น Region Time IP Condition
Shopify Hydrogen คืออะไร
React Framework Custom Storefront Shopify Remix SSR Streaming Edge Storefront API Cart Checkout Oxygen Hosting Headless Commerce Customizable
ใช้ RBAC ABAC กับ Hydrogen อย่างไร
Middleware ตรวจสิทธิ์ Route Role Admin Staff Customer ABAC Fine-grained Seller Owner Region Casbin OPA Session JWT Authentication
สรุป
Shopify Hydrogen RBAC ABAC Policy Role Attribute Access Control Permission Middleware Casbin OPA Authentication Authorization E-commerce Production Security
