Lightweight open source reCaptcha alternative
轻量级开源 reCaptcha 替代方案
altcha-org / **altcha ** Public
GDPR、WCAG 2.2 AA 和 EAA 合规,具有 PoW 机制和高级反垃圾邮件过滤器的自托管 CAPTCHA 替代方案。 altcha.org
License
MIT license 990 stars 37 forks
ALTCHA
ALTCHA 利用工作量证明机制 (proof-of-work mechanism) 来保护您的网站、API 和在线服务免受垃圾邮件和滥用。与传统解决方案不同,ALTCHA 是自托管的,不依赖于 cookies 或指纹识别,并确保完全的用户隐私。它完全符合 GDPR、WCAG 2.2 AA-level 以及 European Accessibility Act。
欲了解更多详情,请访问 ALTCHA。
功能
- 流畅的体验: 使用工作量证明 (PoW) 而不是视觉谜题,确保无缝的用户体验。
- 无 Cookie 设计: 默认情况下构建为符合 GDPR 标准,没有 cookies 或跟踪。
- 完全可访问: 符合 WCAG 2.2 AA-level 标准并符合 European Accessibility Act (EAA)。
- 轻量级: 最小的包大小,可实现快速页面加载和最佳性能。
- 自托管: 独立运行,不依赖于第三方服务。
- 提供 SaaS 选项: 通过 altcha.org 上的 SaaS API 快速入门。
示例
服务器集成
CMS
更多反垃圾邮件解决方案
- Spam Filter - 通过分类数据来阻止复杂的攻击和人工生成的垃圾邮件。
使用方法
ALTCHA widget 以 "Web Component" 形式分发,并 支持所有现代浏览器。
1. 安装 ALTCHA
npm install altcha
在主文件中导入 altcha
:
import 'altcha';
或将 <script>
标签插入您的网站:
<script async defer src="/altcha.js" type="module"></script>
CDN: https://cdn.jsdelivr.net/gh/altcha-org/altcha@main/dist/altcha.min.js
2. 在您的表单中使用 <altcha-widget>
标签
<form>
<altcha-widget
challengeurl="https://..."
></altcha-widget>
</form>
请参阅下面的 configuration 或访问 网站集成文档。
3. 将 ALTCHA 与您的服务器集成
请参阅 服务器文档 以了解更多详细信息。
包大小
ALTCHA 的默认包很轻量级,它将所有资源(包括 CSS 和 JavaScript Web Worker)合并到一个文件中。GZIP 压缩后,总大小仅为 17 kB,这使得 ALTCHA 的 widget 比 reCAPTCHA 小 94%。
| Distribution | Size (GZIPped) | | ------------- | ------------- | | ALTCHA (v1.x) | 17 kB | | hCaptcha | 48+ kB | | reCAPTCHA | 270+ kB |
内容安全策略 (CSP)
WebComponent 的默认分发包在一个文件中包含了样式和 worker。这可能会导致严格 CSP 规则出现问题。如果需要严格的 CSP 合规性,请考虑使用位于 /dist_external
目录中的脚本。有关更多详细信息,请参阅 documentation。
Configuration
必需选项(至少需要一个):
- challengeurl: 用于从服务器获取 challenge 的 URL。请参阅 server integration。
- challengejson: JSON 编码的 challenge 数据。如果避免向
challengeurl
发送 HTTP 请求,请在此处提供数据。
附加选项:
- auto: 无需用户交互即可自动验证(可能的值:
off
、onfocus
、onload
、onsubmit
)。 - customfetch: 用于检索 challenge 的自定义
fetch
函数。接受url: string
和init: RequestInit
作为参数,并且必须返回一个Response
对象。 - delay: 验证前的以毫秒为单位的人为延迟(默认为 0)。
- expire: Challenge 过期时间(以毫秒为单位)。
- floating: 启用浮动 UI(可能的值:
auto
、top
、bottom
)。 - floatinganchor: 将浮动 UI 附加到的 "anchor" 的 CSS 选择器(默认为相关表单中的
button[type="submit"]
)。 - floatingoffset: 浮动 UI 距离 anchor 元素的 Y 轴偏移量(以像素为单位,默认为
12
)。 - floatingpersist: 验证后是否 "persist"(保持可见)浮动 widget(可能的值:
true
|false
|focus
;默认为false
,表示 widget 将隐藏)。 - hidefooter: 隐藏页脚(ALTCHA 链接)。
- hidelogo: 隐藏 ALTCHA 徽标。
- id: 复选框
id
属性。 对于同一页面上的 widget 的多个实例很有用。 - maxnumber: 要迭代到的最大数字(默认为 1,000,000)。
- name: 包含 payload 的隐藏字段的名称(默认为 "altcha")。
- strings: JSON 编码的翻译字符串。请参阅 customization。
- refetchonexpire: challenge 过期时自动重新获取并重新验证(默认为 true)。
- workers: 用于 PoW 的 worker 数量(默认为
navigator.hardwareConcurrency || 8
,最大值16
)。 - workerurl: Worker 脚本的 URL(默认为
./worker.js
,仅适用于external
构建)。
与垃圾邮件过滤器相关的选项:
- blockspam: 仅与
spamfilter
选项一起使用。如果启用,它将阻止表单提交,并且如果垃圾邮件过滤器返回负面分类,则验证将失败。 这可以防止表单提交。 - spamfilter: 启用 Spam Filter。
- verifyurl: 用于服务器端验证请求的 URL。使用
spamfilter
选项时,会自动配置此选项。 仅在使用自定义服务器实现时才覆盖此设置。
数据混淆选项:
- obfuscated: 作为 base64 编码字符串提供的 混淆数据(需要
altcha/obfuscation
plugin)。 仅在没有challengeurl
/challengejson
的情况下使用。
开发/测试选项:
- debug: 在控制台中打印日志消息。
- mockerror: 导致验证始终因“mock”错误而失败。
- test: 在 widget 中生成一个 "mock" challenge,绕过对
challengeurl
的请求。
插件
版本 0.9.x 引入了可以通过导入单个 plugin 脚本来启用的 plugins:
import 'altcha/obfuscation';
import 'altcha';
建议在主 altcha
包 之前 导入 plugin,以确保在创建任何 widget 实例之前正确注册。
altcha
包中内置的可用 plugin:
altcha/analytics
: 使用 ALTCHA Forms 启用分析。 请参阅 HTML submissions documentation。altcha/obfuscation
: 启用 obfuscation 用于敏感数据,例如电子邮件地址或电话号码。altcha/upload
: 启用从type=file
字段到 ALTCHA Forms 的文件上传。 请参阅 HTML submissions documentation。
要为 widget 的特定实例启用特定 plugin,请在 widget 标签中使用 plugins
属性。 列出要启用的 plugin 的名称,用逗号分隔,例如 plugins="analytics,obfuscation"
。 仍然需要按照上述方式导入 plugin。 plugins
属性仅指定哪些 plugin 应为该实例处于活动状态,即使已导入其他 plugin。
Programmatic Configuration
要以编程方式配置 widget,请使用 configure()
方法:
document.querySelector('#altcha').configure({
challenge: {
algorithm: 'SHA-256',
challenge: '...',
salt: '...',
signature: '...',
},
strings: {
label: 'Verify',
},
});
可用的配置选项:
export interface Configure {
auto?: 'off' | 'onfocus' | 'onload' | 'onsubmit';
challenge?: {
algorithm: string;
challenge: string;
maxnumber?: number;
salt: string;
signature: string;
};
challengeurl?: string;
customfetch?: string | ((url: string, init?: RequestInit) => Promise<Response>);
debug?: boolean;
delay?: number;
expire?: number;
floating?: 'auto' | 'top' | 'bottom';
floatinganchor?: string;
floatingoffset?: number;
floatingpersist?: boolean | 'focus';
hidefooter?: boolean;
hidelogo?: boolean;
maxnumber?: number;
mockerror?: boolean;
name?: string;
obfuscated?: string;
refetchonexpire?: boolean;
spamfilter?: boolean | 'ipAddress' | SpamFilter;
strings?: {
error: string;
expired: string;
footer: string;
label: string;
verified: string;
verifying: string;
waitAlert: string;
}
test?: boolean | number | 'delay';
verifyurl?: string;
workers?: number;
workerurl?: string;
}
自定义 fetch
函数
在从服务器请求 challenge 时,widget 不会发送 cookies(即,它不使用 credentials: 'include'
)。 要修改此行为或添加自定义请求标头,请使用 customfetch
配置选项。 此选项允许您定义自定义请求函数。
自定义函数必须返回一个 Response
对象。
发送 Cookies
要在请求中包含 cookies,请使用 credentials: 'include'
:
function altchaCustomFetch(url: string, init: RequestInit) {
return fetch(url, {
...init,
credentials: 'include', // Include cookies with the request
});
}
有关可能的请求选项的更多详细信息,请参阅 Request
文档。
使用 customfetch
customfetch
选项可以接受:
- 一个
string
(全局上下文中定义的全局可访问函数的名称,例如window
),或者 - 函数本身。
用法示例
<altcha-widget
challengeurl="https://example.com/challenge"
customfetch="altchaCustomFetch"
></altcha-widget>
事件
- load - widget 加载时触发。在此事件之后,导出的方法可用。
- serververification - 服务器验证时触发(仅与
spamfilter
结合使用)。 - statechange - 每当内部
state
更改时触发。 - verified - challenge 验证时触发。
enum State {
ERROR = 'error',
VERIFIED = 'verified',
VERIFYING = 'verifying',
UNVERIFIED = 'unverified',
EXPIRED = 'expired',
};
使用事件:
document.querySelector('#altcha').addEventListener('statechange', (ev) => {
// See enum State above
console.log('state:', ev.detail.state);
});
重要说明:
编程配置和事件侦听器都必须在 ALTCHA 脚本加载后调用/附加,例如在 window.addEventListener('load', ...)
中。
垃圾邮件过滤器
widget 与 ALTCHA 的 反垃圾邮件解决方案 集成,以允许检查提交的表单数据是否存在潜在的垃圾邮件。
垃圾邮件过滤器 API 分析提交的数据中的各种信号,以确定它是否表现出垃圾邮件的特征。 这种非侵入式过滤有助于减少垃圾邮件提交,而不会让合法用户感到沮丧。
垃圾邮件过滤器配置
可以通过将 spamfilter
选项设置为 true
或 ipAddress
(仅验证 IP 地址和时区)来使用默认配置启用垃圾邮件过滤器,或者可以使用以下配置架构对其进行自定义:
interface SpamFilter {
blockedCountries?: string[];
classifier?: string;
disableRules?: string[];
email?: string | false;
expectedCountries?: string[];
expectedLanguages?: string[];
fields?: string[] | false;
ipAddress?: string | false;
text?: string | string[];
timeZone?: string | false;
}
SpamFilter 配置选项:
- blockedCountries - 您想要阻止的国家/地区代码(ISO 3166 alpha-2)数组。
- classifier - 强制使用特定的分类器。
- disableRules - 要禁用的规则数组。
- email - 用户电子邮件的输入字段的名称。 使用
false
禁用电子邮件检查。 - expectedCountries - 以 2 字母代码(ISO 3166-1 alpha-2)表示的预期国家/地区数组。
- expectedLanguages - 以 2 字母代码(ISO 639 alpha-2)表示的预期语言数组。
- fields - 要发送到垃圾邮件过滤器的输入名称数组。
- ipAddress - 自动检测用户的 IP,但可以使用
false
覆盖或禁用。 - text - 要分类的文本。 也可以提交字符串数组。
- timeZone - 自动检测用户的时区,但可以使用
false
覆盖或禁用。
要将电子邮件字段包含到 fields
中(以便更轻松地进行服务器端验证),请使用 spamfilter.fields: string[]
选项配置输入名称列表。
从垃圾邮件检查中排除输入
默认情况下,将对父表单中的所有文本输入和 textarea 进行垃圾邮件检查。 要排除特定的输入,请添加 data-no-spamfilter
属性。 或者,使用 fields
配置选项显式列出选中的字段。
贡献
请参阅 Contributing Guide 并请遵循我们的 Code of Conduct。
赞助
该项目由 BAUSW.com - Digital Construction Site Diary 赞助,通过实时文档提高建筑项目的透明度和信任度。
License
MIT
关于
GDPR、WCAG 2.2 AA 和 EAA 合规,具有 PoW 机制和高级反垃圾邮件过滤器的自托管 CAPTCHA 替代方案。 altcha.org
Topics
recaptcha captcha svelte wcag spam-prevention spam-protection antispam spam-filtering spam-detection ddos-mitigation proof-of-work captcha-alternative ddos-protection webcomponent hcaptcha spam-api