8

我不是機器人版 reCAPTCHA 筆記

 2 years ago
source link: https://blog.darkthread.net/blog/recaptcha-not-robot-notes/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

我不是機器人版 reCAPTCHA 筆記

2021-11-28 04:30 PM 5 2,855

10 年前舊版部落格 CAPTCHA 被攻破遭人狂塞垃圾留言,當時換成卡內基美隆大學發明,能有效阻擋機器人兼邀請人類參與古代書籍數位化的 reCAPTCHA,但第一代 reCAPTCHA 疑似被破解,後來才換成自己寫的陽春版加減計算 CAPTCHA。(防護力跟 reCAPTCHA 無法相提並論,但冷門又無利可圖也是種抗體)

2009 reCAPTCHA 被 Google 收購,讓它替大家數位化 18 世紀以來的「紐約時報」以及 Google Books。2014 Google 想出好點子(noCAPTCHA reCAPTCHA),用「勾一下"我不是機器人"」取代歪七扭八鬼才看得懂的英數字頗受好評。過去的扭曲文字圖案為了抵抗日益強大的 AI,導致人類答對率只有 33%、電腦反而能答對 99% 的扭曲結果。noCAPTCHA 採用另一種戰略,在點選「我不是機器人」時傳送一組資料到 Google 伺服器,包含 Google 偷偷記錄的 IP 位址、國家、時間,以及打勾之前的滑鼠軌跡、網頁捲動紀錄等,藉此分析背後是真人操作還是自動程式,遇到無法確定時再祭出圖片挑選挑戰: 參考資料:為什麼只要勾選「我不是機器人」,Google 就知道你不是機器人? by 科技報橘

(傳說中的大魔王挑戰題)

最近跟人討論到 reCAPTCHA,事隔多年,當年知識已不敷使用,故再整理筆記一篇以備不時之需。

reCAPTCHA 版本

目前 reCAPTCHA 共有 v2、v3、Enterprise 三種版本。

v2 除了我們熟知的「我不是機器人」勾選方塊,還有一種隱形模式,用點擊原本登入或送出鈕時取代勾選我不是機器人動作,另外 v2 也有給 Android APP 的版本。

v3 則沒有「我不是機器人」勾選方塊,以純 JavaScript 回傳一個真人指標,1.0 代表操作自然很像真人,0.0 意味極有可能是機器人,程式端再可此決定要不要啟動第二因素(簡訊、OTP)認證等額外驗證機制,使用 v3 必須搭配自訂驗證關卡,實作上較麻煩。

至於 Enterprise 版,則多了風險模型、機器學習模型、Android/iOS SDK、高精確度風險指標... 等進階功能,並提供技術支援。另外,v2/v3 有每個月一百萬次的使用上限,若用量大於一百萬,Enterprise 是唯一選擇。Enterprise 有每月一百萬次的免費額度,超過上限一千萬次以下每 1000 次收費一美元,超過一千萬次請電洽。

一般中小型應用,v2 應是較簡便的選擇。

【參考資料】

reCAPTCHA Key

要使用 reCAPTCHA 需先申請兩支 API Key,一支寫在前端 HTML 裡,另一支呼叫 Google API 取得驗證結果要用。申請網站在 https://www.google.com/recaptcha/admin,使用 Gmail 帳號登入,若從未申請過會跳到註冊新網站頁面:

  1. 識別這組 Key 用的標籤文字
  2. reCAPTCHA 類型
  3. 應用網域(方便本機測試可加 localhost)
  4. 登入 Gmail 是預設擁有者,可加入其他管理者
  5. 需接受服務條款(同意啦,哪次不同意?)
  6. 發生問題或流量異常時發送通知

申請好再次登入 https://www.google.com/recaptcha/admin 會進入管理晝面,若你有多組 Key,可從左邊清單選取標籤,右邊齒輪圖示點下去可修改設定及查看 API Key:

Key 有兩組,上面的寫在 HTML 裡,下面的用在 Server 端呼叫 Google API 時:

在網頁加入 reCAPTCHA

終於到了開心的 Coding 時間。我用 ASPX 示範,大家直接看 Code 吧,程式很簡單,我就不多廢話了。

<%@ Page Language="C#" %>
<%@ Import Namespace="Newtonsoft.Json" %>
<%@ Import Namespace="Newtonsoft.Json.Linq" %>
<script runat="server">
protected string Message = "";
void Page_Load(object sender, EventArgs e)
{
	if (Request.HttpMethod == "POST") 
	{
		var apiKey = "6LeH...oWsC";
		var url = "https://www.google.com/recaptcha/api/siteverify";
		var wc = new System.Net.WebClient();
		wc.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
		var data = "secret=" + apiKey + "&response=" + Request.Form["g-recaptcha-response"];
		var json = wc.UploadString(url, data);
		// JSON 反序化取 .success 屬性 true/false 判斷
		var success = JsonConvert.DeserializeObject<JObject>(json).Value<bool>("success");
		if (!success) {
			Message = "驗證碼有誤";
			return;
		}
		// TODO: 檢查帳號密碼
		Message = "確認過眼神,你不是機器人,但程式還沒完成";
	}
}
</script>

<!DOCTYPE html>

<html>
<head>
	<meta charset="utf-8">
	<title>reCaptcha Test</title>
	<script src="https://www.google.com/recaptcha/api.js" async defer></script>
	<style>
		form > div { padding: 6px; font-size: 10pt; }
		div.msg { color: orangered; }
	</style>
</head>
<body>
	<form method="post">
		<div>帳號:<input type="text" name="acnt" placeholder="Username" /></div>
		<div>密碼:<input type="password" name="pwd" /></div>
		<div class="g-recaptcha" data-sitekey="6LeH...T2d0"></div>
		<div><button>登入</button></div>
		<div class="msg"><%= Message %></div>
	</form>
</body>
</html>

防火牆設定

由於伺服器與呼叫 Google WebAPI,若伺服器位於網路受限環境,需開通防火牆,參考 Wiki 文件,因開放的 IP 較多且為網段,建議透過 DNS 查詢取得,Linux 可用 dig -t TXT _netblocks.google.com,Windows 的話為nslookup -type=TXT _netblocks.google.com


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK