Scrapebase + Permit.io:授权网页抓取
这是Permit.io 授权挑战赛的参赛作品:API-First 授权重塑
我建造了什么
我构建了Scrapebase——一个具有分层访问控制的 Web 数据抓取服务,它演示了使用 Permit.io 实现 API 优先授权的功能。该项目使用 Permit.io 的策略即代码方法,将业务逻辑与授权问题分离。
在许多应用程序中,授权都是事后才考虑的,这会导致安全漏洞和技术债务。Scrapebase 演示了如何从一开始就将授权作为首要考虑事项进行构建。
截图:演示页面:点击
主要特点
- 分层服务级别:免费、专业和管理级别,具有不同的功能
- API 密钥认证:使用 API 密钥进行简单身份验证
- 基于角色的访问控制:通过 Permit.io 管理权限
- 域名黑名单系统:敏感域名的资源级限制
- 文本处理:基于角色限制的基本和高级文本处理
基于角色的能力
特征 | 免费用户 | 专业用户 | 行政 |
---|---|---|---|
基本抓取 | ✅ | ✅ | ✅ |
高级抓取 | ❌ | ✅ | ✅ |
文本清理 | ✅ | ✅ | ✅ |
AI摘要 | ❌ | ✅ | ✅ |
查看黑名单 | ✅ | ✅ | ✅ |
管理黑名单 | ❌ | ❌ | ✅ |
访问黑名单域名 | ❌ | ❌ | ✅ |
演示
现场试用:https://scrapebase-permit.up.railway.app/
测试凭证:
- 免费用户:
newuser
/2025DEVChallenge
- 行政:
admin
/2025DEVChallenge
项目回购
步骤 1:克隆存储库
存储库:github.com/0xtamizh/scrapebase-permit-IO
https://github.com/0xtamizh/scrapebase-permit-IO.git
cd scrapebase-permit-IO
第 2 步:设置 Permit.io
- 在Permit.io创建一个免费帐户
- 创建新项目
- 设置:
- 资源类型:
website
- 操作:
scrape_basic
,scrape_advanced
- 角色:
free_user
,,pro_user
admin
- 资源类型:
- 按照上述说明配置角色权限
- 从仪表板生成环境 API 密钥
步骤3:配置环境变量
.env
在项目根目录中创建一个文件:
# Permit.io
PERMIT_API_KEY=permit_env_YOUR_ENVIRONMENT_KEY
# API Keys for different user tiers
FREE_API_KEY=2025DEVChallenge_free
PRO_API_KEY=2025DEVChallenge_pro
ADMIN_API_KEY=2025DEVChallenge_admin
# Optional: For AI summarization
DEEPINFRA_API_KEY=your_deepinfra_key
# Server configuration
PORT=8080
NODE_ENV=development
# Browser manager settings
MAX_CONCURRENT_REQUESTS=50
REQUEST_TIMEOUT=60000
QUEUE_TIMEOUT=120000
步骤 4:安装依赖项并运行
# Install dependencies
npm install
# Make sure to comment this line in src/utils/browserManager
//executablePath: process.env.CHROMIUM_PATH || '/usr/bin/chromium-browser', comment this line so it will use default chromium browser on your device
# Run in development mode
npm run dev
步骤 5:测试应用程序
使用用户界面:
- 在浏览器中打开http://localhost:8080
- 使用提供的凭证“登录”
- 用户凭证:
newuser
/2025DEVChallenge
- 管理员凭据:
admin
/2025DEVChallenge
- 用户凭证:
- 在基本(免费)和专业计划之间切换
- 输入要抓取的域名(例如 example.com)
直接使用 API:
# Test with free user
curl -X POST http://localhost:8080/api/processLinks \
-H "Content-Type: application/json" \
-H "x-api-key: 2025DEVChallenge_free" \
-d '{"url": "https://example.com"}'
# Test with admin user
curl -X POST http://localhost:8080/api/processLinks \
-H "Content-Type: application/json" \
-H "x-api-key: 2025DEVChallenge_admin" \
-d '{"url": "https://example.com", "advanced": true}'
# Get blacklist
curl http://localhost:8080/api/blacklist \
-H "x-api-key: 2025DEVChallenge_free"
# Add domain to blacklist (admin only)
curl -X POST http://localhost:8080/api/blacklist \
-H "Content-Type: application/json" \
-H "x-api-key: 2025DEVChallenge_admin" \
-d '{"domain": "example.com"}'
API-First 授权
核心授权流程
x-api-key
用户发送带有标头的请求permitAuth
中间件拦截请求- 中间件将 API 密钥映射到用户角色
- 用户已同步至 Permit.io
- 针对 Permit.io 云 PDP 运行权限检查
- 根据策略决定允许或拒绝请求
┌──────────┐ ┌───────────────┐ ┌────────────┐ ┌──────────────┐
│ Client │───▶│ Scrapebase API│───▶│permitAuth │───▶│ Permit.io │
│ │◀───│ │◀───│ middleware │◀───│ Cloud PDP │
└──────────┘ └───────────────┘ └────────────┘ └──────────────┘
│ ▲
│ │
└────────────────────────────────────────────────────────┘
Permission policies defined in Permit.io dashboard
执行
中间件permitAuth
处理角色分配和权限执行:
// Role assignment based on API key
switch (apiKey) {
case process.env.ADMIN_API_KEY:
userKey = '2025DEVChallenge_admin';
tier = 'admin';
break;
// ...other keys
}
// User sync and permission check
await permit.api.syncUser({
key: userKey,
email: `${userKey}@scrapebase.xyz`,
attributes: { tier, roles: [tier] }
});
const permissionCheck = await permit.check(user.key, action, 'website');
仪表板配置
为了使权限正常工作,您必须在 Permit.io 仪表板中配置角色及其允许的操作:
- 创建资源类型
website
- 创建动作
scrape_basic
和scrape_advanced
- 创建角色
free_user
、、pro_user
和admin
- 为角色分配权限:
free_user
:scrape_basic
可以website
pro_user
:可以scrape_basic
继续scrape_advanced
website
admin
:可以做所有事情website
在 Permit.io 仪表板中配置资源类型和操作
故障排除 -> 检查 repo README
面临的挑战
云 PDP 限制
最初,我尝试通过传递资源属性来实现基于属性的访问控制(ABAC):
// This DIDN'T work with cloud PDP
const resource = {
type: 'website',
key: hostname,
attributes: {
is_blacklisted: isBlacklistedDomain
}
};
const permissionCheck = await permit.check(user.key, action, resource);
云端 PDP 返回了 501 错误,因为它仅支持基本 RBAC。我不得不简化为纯 RBAC 方法:
// This works with cloud PDP
const permissionCheck = await permit.check(user.key, action, resourceType);
我的旅程
我为什么要建造这个
传统的授权方法通常会导致权限检查分散在整个应用程序代码中,造成维护难题和安全风险。我创建了 Scrapebase,旨在演示现代应用程序如何将外部化授权作为核心架构原则。
Scrapebase 不仅仅是另一个 CRUD 应用程序 - 它还解决了具有有意义的访问控制要求的实际用例(网络抓取):
- 分层服务级别与 SaaS 订阅模式相似
- 需要提升权限的管理功能
- 通过域名黑名单系统进行基于资源的限制
我学到了什么
使用 Permit.io 构建 Scrapebase 教会了我如何:
-
技术优势
- 授权与业务逻辑分离
- 无需更改代码的外部策略管理
- 可从 RBAC 扩展到 ABAC
-
商业利益
- 非开发人员可以管理权限
- 集中策略管理
- 通过一致执行提高安全性
-
开发者体验
- 更清洁的代码库
- 专注于核心功能
- 更好的可维护性
为什么 Permit.io 适用于 SaaS
Permit.io 非常适合 SaaS 应用程序,因为它:
- 集中代码库之外的策略管理
- 为非开发人员提供配置权限的仪表板
- 随着需求的增长,可以从简单的 RBAC 扩展到复杂的 ABAC
- 提供合规性和调试的审计日志
这种外部化方法使业务利益相关者能够直接通过 Permit.io 仪表板管理授权策略,而开发人员则专注于构建功能 - 这是精心设计的 API 优先授权系统的标志。
未来的改进
如果有更多时间,我会:
- 设置本地 PDP 以启用具有资源属性的 ABAC
- 实施租户隔离以支持多租户
- 在管理仪表板中添加 UI 组件以查看权限审计日志
- 创建超越三层级的更细粒度的角色和权限
- 添加用户管理部分以通过 UI 分配角色
通过 Permit.io 实现这些控制而不是对其进行硬编码,Scrapebase 展示了如何通过声明性策略而不是命令式代码来管理授权 - 实现了真正 API 优先授权的承诺。
文章来源:https://dev.to/tamizhme/scrapebase-permitio-web-scraping-with-authorization-1a9d