节点的SDK城堡
官方节点Js SDK为 城堡. Castle分析网络和移动应用程序中的用户行为,以便在欺诈发生前停止.
这个包裹是薄薄的依赖性灯光包裹 城堡 HTTP API它揭露:
- 风险评估 —— 说
POST /v1/risk, (中文(简体) ),POST /v1/filter - 事件记录 —— 说
POST /v1/log(火与忘,无判决 - 列表项目( L) —完整 CRUD + 搜索 + 计数 + 批次
- 隐私/ GDPR —— 说
POST财务报告和审定财务报表DELETE /v1/privacy/users(第15和17条) - 活动 (企业)——搜索、小组和计划
- Webhook 签名验证 - 验证
X-Castle-Signature - 安全模式 – 从浏览器发送的签名用户ID
每一有效载荷的受支持事件和JSON形状的完整清单记录在 https://reference.castle.io 页面存档备份,存于互联网档案馆。 。 。 .
所需资源
- 节点.js
>= 20(SDK使用内置全球fetch编号 :AbortSignal(中文(简体) ) - A 类 城堡 API 秘密
一揽子船舶,包括无害环境管理和共同JS,因此 import 财务报告和审定财务报表 require 工作从盒子.
安装
npm install --save @castleio/sdk
yarn add @castleio/sdk
快开始
import { Castle, ContextPrepareService } from '@castleio/sdk';
const castle = new Castle({ apiSecret: process.env.CASTLE_API_SECRET });
const context = ContextPrepareService.call(
req,
undefined,
castle.configuration
);
const verdict = await castle.risk({
type: '$login',
status: '$succeeded',
request_token: req.body.castle_request_token,
user: { id: '12345', email: '[email protected]' },
context,
});
switch (verdict.policy?.action) {
case 'deny':
// block the user
break;
case 'challenge':
// send 2FA / additional verification
break;
default:
// allow
}
带有 commonJS :
const { Castle, ContextPrepareService } = require('@castleio/sdk');
ContextPrepareService.call(request, options, configuration) 从节点提取 Castle 所需的 IP 和信头 request 对象。 见 高级配置 用于解析页眉允许/拒绝列表和代理链.
配置
库配置为每个 Castle 实例:
import { Castle, FailoverStrategy } from '@castleio/sdk';
const castle = new Castle({
apiSecret: process.env.CASTLE_API_SECRET,
// Automatic verdict from `risk`/`filter` when Castle is unreachable or
// times out. One of FailoverStrategy.allow (default), .deny, .challenge.
failoverStrategy: FailoverStrategy.allow,
// Request timeout in milliseconds before the failover strategy kicks in.
timeout: 1500,
// Logs Castle API requests and responses; must respond to `info`.
logger: console,
});
配置选项
| 选项 | 类型 | 默认 | 说明 |
|---|---|---|---|
apiSecret | string | API 密码 仪表板。 。 。 . | |
timeout | number | 1500 | 返回故障策略前的时间为毫秒. |
failoverStrategy | FailoverStrategy | FailoverStrategy.allow | 自动 risk 超时响应 : allow, (中文(简体) ), deny,或 challenge。 。 。 . |
logger | object | 日志 Castle API 请求/答复;必须响应 info。 。 。 . | |
doNotTrack | boolean | false | 何时 true并触发失败 risk在开发和测试方面很有用. |
allowlisted | string[] | [] | 严格的页眉允许列表(参见 页眉允许/ 拒绝列表) (中文(简体) ). |
denylisted | string[] | [] | 除了总是被堵住的外, 总是要擦去的 Cookie 编号 : Authorization。 。 。 . |
ipHeaders | string[] | [] | 自定义读取客户端 IP 的标题( 见 客户端IP检测) (中文(简体) ). |
trustedProxies | (string | RegExp)[] | [] | 已知代理IP (字符串或 regexes). 挑这个 或者说 trustedProxyDepth从来没有两者. |
trustedProxyDepth | number | 0 | 链中已知的可信任代理数 。 挑这个 或者说 trustedProxies从来没有两者. |
trustProxyChain | boolean | false | 相信整个人 X-Forwarded-For 链条. 警告: 滥交——恶意代理可以骗取客户IP. |
baseUrl | string | https://api.castle.io/v1 | 基地城堡 API URL. |
多环境/多租户
每个 Castle 所以多重环境或租户只是多重情况:
const castleTenantA = new Castle({
apiSecret: process.env.CASTLE_API_SECRET_TENANT_A,
});
const castleTenantB = new Castle({
apiSecret: process.env.CASTLE_API_SECRET_TENANT_B,
});
使用量
所有端点都是在 a 上的同步方法 Castle 举个例子.
风险
评价高风险事件(记录、登记、密码重置、交易)。 返回判决(policy.action加上风险分数和信号.
await castle.risk({
type: '$login',
status: '$succeeded',
request_token: req.body.castle_request_token,
user: { id: '12345', email: '[email protected]' },
context,
});
过滤器
链条早期的阻塞bots和不良流量(典型的注册). 反应形状与"风险"相同.
await castle.filter({
type: '$registration',
status: '$attempted',
request_token: req.body.castle_request_token,
params: { email: '[email protected]' },
context,
});
日志
火灾和遗忘事件记录;没有判决。 对在仪表板上应该可见但不需要实时决定的事件有用.
await castle.log({
type: '$profile_update',
status: '$succeeded',
user: { id: '12345' },
context,
});
列表项目( L)
列表允许您组织用户、IP、交易或任何自定义属性,并在允许/拒绝列表时将其用于策略:
const list = await castle.createList({
name: 'Trusted IPs',
color: 'green',
primary_field: 'ip.address',
});
await castle.createListItem({
list_id: list.id,
primary_value: '1.2.3.4',
author: { type: '$analyst_email', identifier: '[email protected]' },
});
await castle.searchListItems({
list_id: list.id,
filters: [{ field: 'primary_value', op: '$eq', value: '1.2.3.4' }],
});
可用方法: createList, (中文(简体) ), fetchAllLists, (中文(简体) ), fetchList, (中文(简体) ), updateList, (中文(简体) ), deleteList, (中文(简体) ), searchLists, (中文(简体) ), createListItem, (中文(简体) ), batchUpdateListItems, (中文(简体) ), fetchListItem, (中文(简体) ), searchListItems, (中文(简体) ), countListItems, (中文(简体) ), updateListItem, (中文(简体) ), archiveListItem, (中文(简体) ), unarchiveListItem。 。 。 .
隐私( GDPR)
第15条(使用权)和第17条(被遗忘的权利) /v1/privacy/users。两者都使用 identifier 财务报告和审定财务报表 identifier_type (单位:千美元)$id 或者说 $email:
await castle.requestUserData({
identifier: '[email protected]',
identifier_type: '$email',
});
await castle.deleteUserData({
identifier: 'user_42',
identifier_type: '$id',
});
活动(企业)
查询,组,并检查存储事件的计划. 使用 queryEvents, (中文(简体) ),
groupEvents,以及 eventsSchema数字 :
await castle.queryEvents({
filters: [
/* ... */
],
});
await castle.groupEvents({
filters: [],
group_by: { fields: [] },
columns: [],
});
await castle.eventsSchema();
searchEvents 财务报告和审定财务报表 getEventsSchema 也可作为以下的别名:
queryEvents 财务报告和审定财务报表 eventsSchema。 。 。 .
Webhook 签名验证
城堡在每一个网页上标出 X-Castle-Signature 头曰. 对照 原始内容 在信任有效载荷之前先请求机体—— verifyWebhookSignature 丢出一个 WebhookVerificationError 不匹配时 :
import express from 'express';
import { WebhookVerificationError } from '@castleio/sdk';
const app = express();
// The signature is computed over the raw body, so capture it as a Buffer.
app.post(
'/castle/webhooks',
express.raw({ type: 'application/json' }),
(req, res) => {
try {
castle.verifyWebhookSignature(req.body, req.get('x-castle-signature'));
} catch (err) {
if (err instanceof WebhookVerificationError) {
return res.sendStatus(400);
}
throw err;
}
const event = JSON.parse(req.body.toString());
// signature is valid; proceed
res.sendStatus(200);
}
);
安全模式
安全模式在用户ID服务器侧上签名,这样在浏览器中不能被篡改. 将签名传递给客户端 castle.js SDK: (英语)
const signature = castle.secureModeSignature('user_123');
签名是用你的API 密钥键入的用户代号HMAC-SHA256的十六进制.
高级配置
默认对大多数部署都有好处. 以下选项仅在您有非三角代理链或严格的标题政策时才重要 .
页眉允许/ 拒绝列表
默认情况下, SDK 发送每个 HTTP 信头, 除非 Cookie 财务报告和审定财务报表 AuthorizationCastle用这些信头来打印请求,所以越广越好.
import { DEFAULT_ALLOWLIST } from '@castleio/sdk';
const castle = new Castle({
apiSecret: process.env.CASTLE_API_SECRET,
// Always-blocked headers (in addition to Cookie/Authorization).
denylisted: ['X-Internal-Header'],
// Strict allow-list mode. Headers outside the list are sent with scrubbed
// values, except User-Agent which is always preserved. If you must use an
// allow list, we recommend starting from the curated default.
allowlisted: DEFAULT_ALLOWLIST,
});
页眉名称对大小写不敏感并接受两者 _ 财务报告和审定财务报表 - 作为分离者。 领先 HTTP_ 前缀自动被剥去.
客户端IP检测
Castle需要原始客户端IP,而不是您的代理机或负载平衡器的IP. SDK读取 X-Forwarded-For 财务报告和审定财务报表 Remote-Addr 默认; 选择 一个 以下战略取决于您的基础设施:
const castle = new Castle({
apiSecret: process.env.CASTLE_API_SECRET,
// 1. Custom header (e.g. Cloudflare's Cf-Connecting-Ip).
ipHeaders: ['Cf-Connecting-Ip'],
// 2. Static, known proxy IPs.
trustedProxies: ['10.0.0.1'],
// 3. Ephemeral proxies but known chain depth.
trustedProxyDepth: 2,
// 4. Last resort: trust the entire X-Forwarded-For chain.
// Warning: vulnerable to header spoofing if a malicious proxy is in path.
trustProxyChain: false,
});
选择 无论是 trustedProxies 或者说 trustedProxyDepth从来没有两者。 导出中的私密/后退范围 TRUSTED_PROXIES 常数总是被认为是信任的.
错误
所有 HTTP/API 例外继承自 APIError。 。 。 . ConfigurationError (设置问题)和 WebhookVerificationError (webhook 签名不匹配) 延伸 Error 直接说 最有用的是:
| 类 | 升起时 |
|---|---|
ConfigurationError | SDK的配置错误(缺少API秘密,糟糕的URL). |
BadRequestError | 400 反应. |
UnauthorizedError | 401 糟糕的API秘诀. |
ForbiddenError | 403 反应. |
NotFoundError | 404 反应. |
InvalidParametersError | 422 附有验证细节的答复. |
InvalidRequestTokenError | 422 - 那个 request_token 缺少或无效. |
RateLimitError | 429 ——退后再试. |
PaymentRequiredError | 402 反应. |
InternalServerError | 5xx 卡塞尔的回复. |
WebhookVerificationError | 网签不符 . |
完整名单中 src/errors.ts。 。 。 .
升级到 3. 0
3.0.0 是一种现代化的释放。 公众API(公共 Castle 分类及其分类
方法)是不变的——大多数项目可以升级而无需更改代码.
改变了什么:
- 遗产终点被移除 .
authenticate, (中文(简体) ),track设备 结束点( e)getDevice, (中文(简体) ),getDevicesForUser, (中文(简体) ),approveDevice, (中文(简体) ),reportDevice(中文(简体) ) 已经消失——使用risk, (中文(简体) ),filter,以及log换句话说 匹配的有效载荷类型 (单位:千美元)Payload, (中文(简体) ),DevicePayload, (中文(简体) ),UserDevicePayload, (中文(简体) ),AuthenticateResult曾经 也删除了.- 如果您以前使用过
reportDevice编号 :approveDevice,管理设备 核准和报告 列表 API 相反(例如:.createListItem编号 :archiveListItem) (中文(简体) ). 见 使用清单的报告装置。 。 。 .
- 如果您以前使用过
- 节点.js
>= 20现在需要. SDK使用运行时间的内置fetch财务报告和审定财务报表AbortSignal改为node-fetch编号 :abort-controller,哪个 不再是依赖关系. - 建立双重无害环境管理+共同JS. 包裹现在暴露出一个合适的
exports地图 单独import财务报告和审定财务报表require出入口和类型定义。 深处 进口dist/从未被支持,并且始终不支持; 从 软件包根 (@castleio/sdk) (中文(简体) ). - 这个
lodash.*微依赖性被取消,以有利于本地的JavaScript; 这是内部的,不影响行为.
如果您先前依赖的是习惯 overrideFetch,它仍然工作——通过任何
fetch- 兼容的执行.
许可证
根据《公约》条款作为公开源码提供 MIT 许可证。 。 。 .