hCaptcha#
前情提要#
我們社團的短網址服務裡面常常出現一些奇怪的網址,我猜可能是有機器人在刷,所以我想加入 captcha 減少這類問題。我選擇的是 hCaptcha ↗ 這套,能不依賴 Google 就盡量不要。
安裝步驟#
申請帳號#
先到 hCaptcha ↗ 註冊、新增一個網站,複製 sitekey (Sites
> site setting
) 和 secret key (Settings
),我們等等會用到
前端#
- 首先引入 script ,在
<head>
加入
<script src="https://hcaptcha.com/1/api.js" async defer></script>
html- 接著在你的
<form>
裡面加入,這邊的your_site_key
就是剛剛複製的那個。記得<form>
的 method 要設成post
<div class="h-captcha" data-sitekey="your_site_key"></div>
html後端(node express)#
-
SECRET
首先,你要把剛剛的SECRET
給 server 知道,我用的是 dotenv,當然其他的套件也是可以。
簡而言之,剛剛複製下來的SECRET
就是用在這裡。 -
驗證 後端我選用的套件是 express-hcaptcha ↗ ,它提供一個 middleware 驗證 hcaptcha 的 token。 按照 README.md 的說明,應該是像這樣就可以了,當驗證通過時就會執行第二個 middleware
const router = require('express').Router();
const captcha = require('express-hcaptcha');
const SECRET = process.env.HCAPTCHA_SECRET_KEY;
if (SECRET) {
// 這個 route 就是本來接收/處理 form 傳遞資料進來來的 route,只是加一個 captcha.middleware.validate(SECRET)
router.post('/', captcha.middleware.validate(SECRET), (req, res, next) => {
res.json({
message: 'verified!',
hcaptcha: req.hcaptcha,
});
});
}
module.exports = router;
js很不幸的,你會發現不管怎麼試,都驗證都不會通過,因為有一個 README.md 沒寫的 bug
- 解 bug
閱讀 express-hcaptcha ↗ 的 source code,你會在 這行 ↗ 發現它用的是
req.body.token
,但是 hCaptcha 的回傳是在req.body.h-captcha-token
裡面 …
有夠蠢的 bug
所以剛剛的程式碼就需要修改一下 在驗證之前先把req.body.h-captcha-token
的內容塞進req.body.token
裡面
const router = require('express').Router();
const captcha = require('express-hcaptcha');
const SECRET = process.env.HCAPTCHA_SECRET_KEY;
if (SECRET) {
router.post(
'/',
(req, res, next) => {
req.body.token = req.body['h-captcha-response'];
next();
},
captcha.middleware.validate(SECRET),
(req, res, next) => {
res.json({
message: 'verified!',
hcaptcha: req.hcaptcha,
});
}
);
}
module.exports = router;
js結論#
看原始碼很重要