Token của reCAPTCHA Enterprise trông giống hệt token reCAPTCHA v3. Khác biệt nằm ở phía server: khi backend của trang gọi projects.assessments.create, Google trả về cả một khối JSON gồm điểm rủi ro, danh sách reasons giải thích vì sao điểm thấp, nhãn Account Defender và trạng thái token.
Bài này mổ xẻ khối JSON đó rồi quay lại phía tự động hóa. Ba điều cần nắm:
- Thử thách phía trình duyệt của Enterprise và v3 là như nhau.
reasonschỉ hiển thị cho người vận hành trang, không cho bên gửi token.- Ở phía solver, khác biệt gói gọn trong một cờ:
enterprise=1.
Luồng assessment: từ trình duyệt tới quyết định cho qua hay chặn
Enterprise chia công việc thành hai nửa tách bạch: client tạo token, server diễn giải token.
Client-side:
1. Load reCAPTCHA Enterprise script
2. Call grecaptcha.enterprise.execute(SITE_KEY, {action: 'LOGIN'})
3. Receive token
4. Send token to your backend
Server-side:
1. Create assessment via Enterprise API
2. Receive detailed risk analysis
3. Make access decision based on score + reasons
4. Optionally annotate the assessment (report fraud/legitimate)
Bước annotate cuối luồng cho phép người vận hành báo ngược cho Google rằng một phiên là gian lận hay hợp lệ; tín hiệu đó tinh chỉnh cách chấm điểm cho site.
reCAPTCHA Enterprise khác reCAPTCHA v3 tiêu chuẩn ở đâu
Gần như mọi khác biệt đều nằm ở phía server, không phải ở thử thách trình duyệt.
| Tính năng | reCAPTCHA v3 (miễn phí) | reCAPTCHA Enterprise |
|---|---|---|
| Chấm điểm | Điểm 0,0–1,0 | Điểm 0,0–1,0 kèm reasons |
| Phân tích rủi ro | Cơ bản | Chi tiết (tín hiệu gian lận, tài khoản) |
| Lý do chấm điểm | Không có | Có, cho từng assessment |
| Account Defender | Không | Có (theo vòng đời tài khoản) |
| Tích hợp WAF | Không | Có (Cloudflare, Fastly, F5) |
| Express assessment | Không | Có (chỉ phía server, không cần JS) |
| Phát hiện rò rỉ mật khẩu | Không | Có |
| Giá | Miễn phí (1 triệu assessment/tháng) | $1 cho mỗi 1.000 assessment |
| Endpoint API | google.com/recaptcha/api/siteverify | recaptchaenterprise.googleapis.com |
Phía client: script khác, token giống
SDK JavaScript
<script src="https://www.google.com/recaptcha/enterprise.js?render=SITE_KEY"></script>
<script>
grecaptcha.enterprise.ready(function() {
grecaptcha.enterprise.execute('SITE_KEY', { action: 'LOGIN' })
.then(function(token) {
// Send token to backend
fetch('/api/verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ token: token })
});
});
});
</script>
Ba chi tiết phân biệt đoạn script này với reCAPTCHA v3:
- URL script là
.../recaptcha/enterprise.jsthay vì.../recaptcha/api.js - Đối tượng API là
grecaptcha.enterprisethay vìgrecaptcha execute()trả về token với định dạng y hệt
Nhận diện Enterprise ngay trong HTML
Hàm dưới tải HTML, tìm recaptcha/enterprise.js rồi trích site key và danh sách action.
import requests
import re
def detect_recaptcha_enterprise(url):
"""Detect if a page uses reCAPTCHA Enterprise."""
html = requests.get(url, timeout=10).text
indicators = {
"is_enterprise": False,
"is_standard": False,
"site_key": None,
"actions": [],
}
# Enterprise detection
if "recaptcha/enterprise.js" in html:
indicators["is_enterprise"] = True
match = re.search(r"render=([A-Za-z0-9_-]+)", html)
if match:
indicators["site_key"] = match.group(1)
# Standard v3 detection
elif "recaptcha/api.js?render=" in html:
indicators["is_standard"] = True
match = re.search(r"render=([A-Za-z0-9_-]+)", html)
if match:
indicators["site_key"] = match.group(1)
# Extract action names
actions = re.findall(r"action:\s*['\"](\w+)['\"]", html)
indicators["actions"] = list(set(actions))
return indicators
print(detect_recaptcha_enterprise("https://staging.example.com/qa-login"))
Danh sách actions quan trọng hơn vẻ ngoài: gửi token kèm action sai thì điểm rơi xuống đáy, dù token vẫn hợp lệ về kỹ thuật.
Assessment API phía server
Tạo assessment bằng thư viện Google Cloud
Đoạn code này chỉ chạy phía người vận hành trang — nơi đọc được mọi tín hiệu.
from google.cloud import recaptchaenterprise_v1
from google.cloud.recaptchaenterprise_v1 import Assessment
def create_assessment(project_id, site_key, token, action):
"""Create a reCAPTCHA Enterprise assessment."""
client = recaptchaenterprise_v1.RecaptchaEnterpriseServiceClient()
event = recaptchaenterprise_v1.Event()
event.site_key = site_key
event.token = token
event.expected_action = action
assessment = recaptchaenterprise_v1.Assessment()
assessment.event = event
request = recaptchaenterprise_v1.CreateAssessmentRequest()
request.assessment = assessment
request.parent = f"projects/{project_id}"
response = client.create_assessment(request)
return response
Cấu trúc phản hồi
{
"name": "projects/123456/assessments/abcdef123",
"event": {
"token": "...",
"siteKey": "6Le...",
"expectedAction": "LOGIN",
"hashedAccountId": "abc123..."
},
"riskAnalysis": {
"score": 0.9,
"reasons": [
"AUTOMATION",
"TOO_MUCH_TRAFFIC"
],
"extendedVerdictReasons": [
"BROWSER_ERROR"
]
},
"tokenProperties": {
"valid": true,
"hostname": "example.com",
"action": "LOGIN",
"createTime": "2025-01-15T10:30:00Z",
"invalidReason": ""
},
"accountDefenderAssessment": {
"labels": ["PROFILE_MATCH"]
}
}
Ba khối đáng đọc:
riskAnalysis— điểm,reasons,extendedVerdictReasons; giá trị chẩn đoán cao nhất.tokenProperties— token hợp lệ hay không, hostname,action; khivalidlà false thìinvalidReasonnói rõ lý do.accountDefenderAssessment— nhãn rủi ro của tài khoản, chỉ có khi gửi kèmhashedAccountId.
Account Defender theo dõi tài khoản qua cả vòng đời
Điểm số chỉ nói về một lần tương tác. Account Defender nhìn tài khoản theo thời gian: thiết bị quen, nhịp đăng nhập, quan hệ với tài khoản khác.
{
"accountDefenderAssessment": {
"labels": [
"PROFILE_MATCH",
"SUSPICIOUS_LOGIN_ACTIVITY",
"SUSPICIOUS_ACCOUNT_CREATION",
"RELATED_ACCOUNTS_NUMBER_HIGH"
]
}
}
| Nhãn | Ý nghĩa |
|---|---|
PROFILE_MATCH |
Hành vi khớp hồ sơ đã biết của tài khoản |
SUSPICIOUS_LOGIN_ACTIVITY |
Đăng nhập lệch chuẩn (thiết bị mới, vị trí lạ) |
SUSPICIOUS_ACCOUNT_CREATION |
Tài khoản có dấu hiệu tạo tự động |
RELATED_ACCOUNTS_NUMBER_HIGH |
Nhiều tài khoản cùng thiết bị hoặc session |
Score reasons: tín hiệu nào kéo điểm xuống
Đây là thứ bản v3 miễn phí không có. Cột tác động chỉ là biên độ tham khảo, không phải con số Google công bố.
| Lý do | Ý nghĩa | Mức tác động lên điểm |
|---|---|---|
AUTOMATION |
User agent tự động hoặc trình duyệt headless | -0,3 đến -0,7 |
UNEXPECTED_ENVIRONMENT |
Môi trường trình duyệt hoặc thiết bị không nhất quán | -0,2 đến -0,4 |
TOO_MUCH_TRAFFIC |
Request quá nhiều từ cùng IP hoặc session | -0,1 đến -0,3 |
UNEXPECTED_USAGE_PATTERNS |
Hành vi lệch khỏi mẫu người dùng thật | -0,2 đến -0,5 |
LOW_CONFIDENCE_SCORE |
Không đủ dữ liệu để kết luận | Thay đổi |
SUSPECTED_CARDING |
Mẫu giao dịch trùng gian lận thẻ tín dụng | -0,3 đến -0,6 |
SUSPECTED_CHARGEBACK |
Rủi ro bồi hoàn từ tín hiệu giao dịch | -0,2 đến -0,4 |
extendedVerdictReasons: lớp chi tiết thứ hai
| Lý do | Ý nghĩa |
|---|---|
BROWSER_ERROR |
JavaScript trong SDK CAPTCHA lỗi khi thực thi |
SITE_MISMATCH |
Token tạo cho site khác với site đang xác minh |
FAILED_TWO_FACTOR |
Xác thực hai bước vừa thất bại gần đây |
Enterprise ở lớp WAF, trước khi request chạm ứng dụng
reCAPTCHA Enterprise cắm được vào WAF, đưa thử thách ra biên mạng thay vì để trong code ứng dụng.
Cloudflare
Request arrives at Cloudflare edge
↓
Cloudflare WAF rule evaluates request
↓
Rule triggers reCAPTCHA Enterprise challenge
↓
Client solves CAPTCHA → token returned
↓
Cloudflare validates token via Enterprise API
↓
If valid + score above threshold → request forwarded to origin
F5 BIG-IP
F5 iRule or policy evaluates request
↓
Triggers reCAPTCHA Enterprise challenge page
↓
Client solves → token validated server-side
↓
F5 forwards or blocks based on assessment score
Điểm chung: token vẫn do trình duyệt tạo, nhưng nơi kiểm tra là biên mạng. Bị chặn ngay từ biên thì bạn không thấy form nào cả — chỉ thấy trang thử thách.
Giải Enterprise trong pipeline tự động hóa
Với một solver API, token Enterprise và token tiêu chuẩn hoạt động như nhau. Bạn chỉ thêm một cờ báo đây là biến thể Enterprise.
Python
import requests
import time
API_KEY = "YOUR_API_KEY"
# Enterprise is solved with the same method
# The solver handles the Enterprise variant automatically
submit = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": "6LcR_RsTAAAAAN_r0GEkGBfq3L7KmU5JbPHJtwNp",
"pageurl": "https://enterprise-site.com/login",
"enterprise": 1, # Flag for Enterprise variant
"json": 1,
})
task_id = submit.json()["request"]
for _ in range(60):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY,
"action": "get",
"id": task_id,
"json": 1,
}).json()
if result.get("status") == 1:
token = result["request"]
print(f"Enterprise token: {token[:50]}...")
break
Vòng lặp hỏi res.php mỗi 5 giây (polling) cho tới khi status bằng 1. Token trả về gắn thẳng vào trường g-recaptcha-response.
Node.js
const axios = require("axios");
async function solveEnterprise(sitekey, pageurl) {
const API_KEY = "YOUR_API_KEY";
const { data: submit } = await axios.post(
"https://ocr.captchaai.com/in.php",
new URLSearchParams({
key: API_KEY,
method: "userrecaptcha",
googlekey: sitekey,
pageurl: pageurl,
enterprise: 1,
json: 1,
})
);
const taskId = submit.request;
for (let i = 0; i < 60; i++) {
await new Promise(r => setTimeout(r, 5000));
const { data: result } = await axios.get(
"https://ocr.captchaai.com/res.php",
{ params: { key: API_KEY, action: "get", id: taskId, json: 1 } }
);
if (result.status === 1) return result.request;
}
throw new Error("Timeout");
}
Phân biệt Enterprise, v3 và v2 trước khi gửi task
Đừng cứng hoá biến thể trong pipeline nhiều trang; hàm dưới phân loại HTML để bạn chọn tham số tại runtime.
def identify_recaptcha_version(html):
"""Determine which reCAPTCHA version a page uses."""
if "recaptcha/enterprise.js" in html:
return "enterprise"
elif "recaptcha/api.js?render=" in html:
return "v3"
elif "g-recaptcha" in html and 'data-size="invisible"' in html:
return "v2_invisible"
elif "g-recaptcha" in html:
return "v2"
else:
return "none"
Chi phí ở hai phía: assessment và thread
Hai dòng chi phí, hai bên trả — lẫn lộn chúng là nguồn gốc của nhiều dự toán sai:
- Bên vận hành trang trả cho Google theo số assessment: 1 triệu đầu mỗi tháng miễn phí, phần vượt tính $1 cho mỗi 1.000 assessment.
- Bên tự động hóa trả cho solver theo thread (luồng giải đồng thời), không theo lần giải. CaptchaAI dùng mô hình này: BASIC ($15/tháng, 5 thread) đủ cho một script tuần tự, ADVANCE ($90/tháng, 50 thread) hợp với nhiều worker song song trong CI.
Đo số task đồng thời ở giờ cao điểm trước khi chọn gói.
Tình huống thực tế: đội sản phẩm Việt Nam tự bật Enterprise
Bạn vừa bật reCAPTCHA Enterprise cho form đăng nhập. Tuần đầu, tỷ lệ đăng nhập giảm và bộ phận hỗ trợ báo có người dùng thật bị chặn. Là bên vận hành trang, bạn đọc được reasons.
Quy trình chẩn đoán:
- Ghi log phản hồi assessment kèm kết quả đăng nhập trong ít nhất một tuần.
- Nhóm các phiên bị chặn theo
reasonsđể biết tín hiệu nào chiếm đa số. - Nếu
UNEXPECTED_ENVIRONMENTdồn vào một nhóm thiết bị, hãy soi các in-app browser phổ biến ở Việt Nam như Zalo hay Facebook — thường là nguồn sai lệch, chứ không phải bot. - Tái hiện luồng trên staging bằng script dùng CaptchaAI, rồi so sánh assessment giữa phiên script và phiên người thật.
hashedAccountId và log assessment gắn với người dùng thật, nên Nghị định 13/2023/NĐ-CP là lý do đủ để chỉ lưu bản băm và đặt hạn xoá log.
Lỗi thường gặp khi làm việc với Enterprise
| Triệu chứng | Nguyên nhân thường gặp | Cách xử lý |
|---|---|---|
| Token bị Assessment API từ chối | Gửi task theo cách bản tiêu chuẩn | Thêm enterprise=1 vào request tới in.php |
| Điểm luôn ở mức 0,1 dù token hợp lệ | action không khớp |
Đối chiếu action với giá trị trang gửi |
SITE_MISMATCH trong reasons |
Token tạo cho tên miền khác | Đảm bảo pageurl khớp chính xác trang đích |
AUTOMATION trong reasons |
Môi trường tạo token bị đánh dấu | CaptchaAI xử lý phần này; nếu lặp lại, liên hệ hỗ trợ |
| Token hợp lệ nhưng trang vẫn chặn | Còn lớp kiểm tra ngoài CAPTCHA | Rà soát WAF, rate limit, lớp phát hiện bot khác |
Câu hỏi thường gặp
Điểm riskAnalysis.score thấp có nghĩa là token bị từ chối không?
Không. Quyết định cho qua hay chặn nằm ở ngưỡng do người vận hành trang tự đặt: mức 0,3 có thể được chấp nhận ở form tìm kiếm nhưng bị chặn ở bước thanh toán.
tokenProperties.valid là true mà trang vẫn chặn thì vấn đề ở đâu?
Token hợp lệ chỉ chứng minh nó được tạo đúng site key, đúng hostname và chưa hết hạn. Trang vẫn có thể chặn vì điểm dưới ngưỡng, vì nhãn Account Defender hoặc vì lớp kiểm tra khác.
Tôi có cần tài khoản Google Cloud để giải CAPTCHA Enterprise không?
Không. Bên giải chỉ cần sitekey công khai trong HTML và một API key của solver. Tài khoản Google Cloud là thứ bên vận hành trang cần để gọi Assessment API.
Enterprise có tốn kém hơn cho bên vận hành trang không?
Có, sau hạn mức miễn phí: phần vượt 1 triệu assessment mỗi tháng tính $1 cho mỗi 1.000 assessment. Với bên gửi token, chi phí không đổi vì gói CaptchaAI tính theo thread.
Tóm tắt
Enterprise không làm thử thách trình duyệt khó hơn — nó làm phần diễn giải phía server giàu thông tin hơn. Nếu bạn vận hành trang, reasons và nhãn Account Defender là công cụ chẩn đoán chính. Nếu bạn ở phía tự động hóa, chỉ cần ba việc: nhận diện recaptcha/enterprise.js, lấy đúng action và thêm enterprise=1 vào task gửi cho CaptchaAI.