CAPTCHA 探索性测试
您可以在审查应用(review apps)和本地开发环境(GDK)中可靠地测试 CAPTCHA。 您始终可以:
- 在支持的地方强制显示 reCAPTCHA。
- 强制显示复选框,而不是寻找和选择街道标志图像。
要设置测试,请按照本页面的配置进行。
使用适当的测试数据
确保您测试的场景已启用 spam/CAPTCHA。例如: 确保您正在编辑公共代码片段(public snippet),因为只有公共代码片段会检查垃圾信息。
启用功能开关
如果 spam/CAPTCHA 支持被功能开关控制,请启用任何相关的功能开关。
设置 Akismet 和 reCAPTCHA
- 设置 reCAPTCHA:
- 查看 GitLab reCAPTCHA 文档。
- 按照Google提供的说明获取官方的 测试 reCAPTCHA 凭据。
- 对于 Site key,使用:
6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI - 对于 Secret key,使用:
6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe
- 对于 Site key,使用:
- 转到 Admin -> Settings -> Reporting 设置:
http://gdk.test:3000/admin/application_settings/reporting#js-spam-settings - 展开 Spam and Anti-bot Protection 部分。
- 选择 Enable reCAPTCHA。除非您正在测试该功能,否则不需要为登录启用。
- 输入 Site key 和 Secret key。
- 设置 Akismet:
- 查看 GitLab 关于 Akismet 的文档。
- 获取一个 Akismet API 密钥。您可以注册 来自 Akismet 的测试密钥。
注册时您必须输入本地主机(如
gdk.test)和电子邮件。 - 转到 GitLab Akismet 设置页面,例如:
http://gdk.test:3000/admin/application_settings/reporting#js-spam-settings - 启用 Akismet 并输入您的 Akismet API key。
- 要强制执行 Akismet 误报垃圾信息检查,请参考
Akismet API 文档 和
Akismet 入门文档 了解更多详情:
- 您可以使用
[email protected]作为作者邮箱,通过以下步骤强制垃圾信息:- 转到用户邮箱设置:
http://gdk.test:3000/-/profile/emails - 将
[email protected]添加为管理员用户的辅助邮箱。 - 在 Rails 控制台中确认:
bin/rails c->User.find_by_username('root').emails.last.confirm - 将此已验证的邮箱切换为您的 primary 邮箱:
- 转到 Avatar dropdown list -> Edit Profile -> Main Settings。
- 对于 Email,输入
[email protected]替换[email protected]。 - 选择 Update Profile Settings 保存更改。
- 转到用户邮箱设置:
- 您可以使用
在 Web UI 中测试
完成上述所有配置后,您就可以测试 CAPTCHA 了。在应用中已有 CAPTCHA 支持的区域进行测试,例如:
- 创建或编辑 issue。
- 创建或编辑公共代码片段。只有 public 代码片段会检查垃圾信息。
在开发环境中测试
通过上述步骤强制启用 Spam Flagging + CAPTCHA 后,您可以使用任何受垃圾信息保护的模型/控制器操作来测试其行为。
测试 CAPTCHA 启用的情况(CONDITIONAL_ALLOW 判决)
如果这些区域启用了 CAPTCHA,您必须解决 CAPTCHA 弹出模态框才能重新提交表单:
- Admin -> Settings -> Reporting -> Spam
- Anti-bot Protection -> Enable reCAPTCHA
测试 CAPTCHA 禁用的情况(DISALLOW 判决)
如果在 Admin -> Settings -> Reporting -> Spam 和 Anti-bot Protection -> Enable reCAPTCHA 中禁用了 CAPTCHA, 则不会显示 CAPTCHA 弹出框。您完全无法提交表单。
渲染 reCAPTCHA 的 HTML 页面
如果您使用 设置 Akismet 和 reCAPTCHA 中列出的 Google 官方测试 reCAPTCHA 凭据, CAPTCHA 响应字符串无关紧要。它可以是任何字符串。如果您使用真实有效的密钥对, 您必须解决 CAPTCHA 以获取有效的 CAPTCHA 响应才能使用。您只能执行一次此操作,并且必须在过期之前执行。
要通过 GraphQL Explorer (http://gdk.test:3000/-/graphql-explorer) 直接测试 GraphQL API,
请通过此表单获取 reCAPTCHA 响应字符串:public/recaptcha.html (http://gdk.test:3000/recaptcha.html):
<html>
<head>
<title>reCAPTCHA demo: Explicit render after an onload callback</title>
<script type="text/javascript">
var onloadCallback = function() {
grecaptcha.render('html_element', {
'sitekey' : '6Ld05AsaAAAAAMsm1yTUp4qsdFARN15rQJPPqv6i'
});
};
function onSubmit() {
window.document.getElementById('recaptchaResponse').innerHTML = grecaptcha.getResponse();
return false;
}
</script>
</head>
<body>
<form onsubmit="return onSubmit()">
<div id="html_element"></div>
<br>
<input type="submit" value="Submit">
</form>
<div>
<h1>recaptchaResponse:</h1>
<div id="recaptchaResponse"></div>
</div>
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit"
async defer>
</script>
</body>
</html>Spam/CAPTCHA API 探索性测试示例
这些部分描述了为 REST 和 GraphQL API 执行手动探索性测试 Spam 和 CAPTCHA 行为各种场景所需的步骤。
对于先决条件,您必须:
- 执行上述所有步骤,在开发环境中启用 Spam 和 CAPTCHA, 并强制表单提交要求 CAPTCHA。
- 确保您已在
/public目录下创建了渲染 CAPTCHA 的 HTML 页面, 该页面包含一个用于手动生成有效 CAPTCHA 响应字符串的表单。 如果您使用 设置 Akismet 和 reCAPTCHA 中列出的 Google 官方测试 reCAPTCHA 凭据, CAPTCHA 响应字符串的内容无关紧要。 - 转到 Admin -> Settings -> Reporting -> Spam and Anti-bot protection。
- 根据您的场景需求,选择或清除 Enable reCAPTCHA 和 Enable Akismet。
以下示例使用代码片段创建作为示例。您也可以使用 代码片段更新、issue 创建或 issue 更新。Issues 和代码片段是唯一具有完整 Spam 和 CAPTCHA 支持的模型。
初始设置
- 创建一个 API token。
- 在终端中导出它以用于 REST 命令:
export PRIVATE_TOKEN=<your_api_token> - 在使用 GraphiQL explorer 之前,确保您已登录到
localhost:3000的 GitLab 开发环境, 因为它使用您的已认证用户作为运行 GraphQL 查询的授权。 - 对于 GraphQL 示例,使用
http://localhost:3000/-/graphql-explorer的 GraphiQL explorer。 - 使用
curl的--include(-i) 选项打印 HTTP 响应头,包括状态码。
场景:Akismet 和 CAPTCHA 启用
在此示例中,Akismet 和 CAPTCHA 已启用:
- 初始请求。
初始请求
此初始请求失败,因为没有提供 CAPTCHA 响应。
REST 请求:
curl --request POST --header "PRIVATE-TOKEN: $PRIVATE_TOKEN" "http://localhost:3000/api/v4/snippets?title=Title&file_name=FileName&content=Content&visibility=public"REST 响应:
{"needs_captcha_response":true,"spam_log_id":42,"captcha_site_key":"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX","message":{"error":"Your snippet has been recognized as spam. Please, change the content or solve the reCAPTCHA to proceed."}}GraphQL 请求:
mutation {
createSnippet(input: {
title: "Title"
visibilityLevel: public
blobActions: [
{
action: create
filePath: "BlobPath"
content: "BlobContent"
}
]
}) {
snippet {
id
title
}
errors
}
}GraphQL 响应:
{
"data": {
"createSnippet": null
},
"errors": [
{
"message": "Request denied. Solve CAPTCHA challenge and retry",
"locations": [
{
"line": 22,
"column": 5
}
],
"path": [
"createSnippet"
],
"extensions": {
"needs_captcha_response": true,
"spam_log_id": 140,
"captcha_site_key": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
}
]
}第二次请求
此请求成功,因为提供了 CAPTCHA 响应。
REST 请求:
export CAPTCHA_RESPONSE="<CAPTCHA response obtained from HTML page to render CAPTCHA>"
export SPAM_LOG_ID="<spam_log_id obtained from initial REST response>"
curl --request POST --header "PRIVATE-TOKEN: $PRIVATE_TOKEN" --header "X-GitLab-Captcha-Response: $CAPTCHA_RESPONSE" --header "X-GitLab-Spam-Log-Id: $SPAM_LOG_ID" "http://localhost:3000/api/v4/snippets?title=Title&file_name=FileName&content=Content&visibility=public"REST 响应:
{"id":42,"title":"Title","description":null,"visibility":"public", "other_fields": "..."}GraphQL 请求:
GitLab GraphiQL 实现不允许传递头部,因此我们必须将其编写为 curl 查询。
这里使用 --data-binary 来正确处理 JSON 嵌入查询中的转义双引号。
export CAPTCHA_RESPONSE="<CAPTCHA response obtained from HTML page to render CAPTCHA>"
export SPAM_LOG_ID="<spam_log_id obtained from initial REST response>"
curl --include "http://localhost:3000/api/graphql" --header "Authorization: Bearer $PRIVATE_TOKEN" --header "Content-Type: application/json" --header "X-GitLab-Captcha-Response: $CAPTCHA_RESPONSE" --header "X-GitLab-Spam-Log-Id: $SPAM_LOG_ID" --request POST --data-binary '{"query": "mutation {createSnippet(input: {title: \"Title\" visibilityLevel: public blobActions: [ { action: create filePath: \"BlobPath\" content: \"BlobContent\" } ] }) { snippet { id title } errors }}"}'GraphQL 响应:
{"data":{"createSnippet":{"snippet":{"id":"gid://gitlab/PersonalSnippet/42","title":"Title"},"errors":[]}}}场景:Akismet 启用,CAPTCHA 禁用
对于此场景,请确保按照上述说明清除 Admin 区域设置中的 Enable reCAPTCHA。 如果未启用 CAPTCHA,任何被标记为潜在垃圾信息的请求都会失败,没有重新提交的机会, 即使如果启用了 CAPTCHA 并成功解决,本可以重新提交。
REST 请求与启用 CAPTCHA 时相同:
curl --request POST --header "PRIVATE-TOKEN: $PRIVATE_TOKEN" "http://localhost:3000/api/v4/snippets?title=Title&file_name=FileName&content=Content&visibility=public"REST 响应:
{"message":{"error":"Your snippet has been recognized as spam and has been discarded."}}GraphQL 请求:
mutation {
createSnippet(input: {
title: "Title"
visibilityLevel: public
blobActions: [
{
action: create
filePath: "BlobPath"
content: "BlobContent"
}
]
}) {
snippet {
id
title
}
errors
}
}GraphQL 响应:
{
"data": {
"createSnippet": null
},
"errors": [
{
"message": "Request denied. Spam detected",
"locations": [
{
"line": 22,
"column": 5
}
],
"path": [
"createSnippet"
],
"extensions": {
"spam": true
}
}
]
}场景:启用 allow_possible_spam 应用设置
启用 allow_possible_spam 应用设置后,API 返回 200 响应。任何
有效请求都会成功,并且不会显示 CAPTCHA,即使该请求被认为是
垃圾信息。