axios で reCAPTCHA のレスポンストークンの検証を行う方法
JavaScript のライブラリ axios で reCAPTCHA のレスポンストークンの検証を行う方法をかんたんにまとめます。
reCAPTCHA は一般に次の 3 ステップで利用するものですが、今回はこのうちの 3 ステップめのサーバーサイドにおける処理が対象です。
- (クライアントサイド)トークンを取得する
- (クライアントサイド)取得したトークンを他のデータといっしょにサーバーサイドに送る
- (サーバーサイド)クライアントから送られたトークンを検証する
動作確認に使った axios のバージョンは 0.20.0
です(バージョンが変わるとあてはまらなくなることもあると思います、参考にされる際は注意してください)。
動作確認は reCAPTCHA v3 だけで行いましたが、検証に利用する API のエンドポイントは v3 も v2 も共通のようなので v2 でも同じだと思います。
axios で reCAPTCHA のレスポンストークンの検証を行う方法
reCAPTCHA のトークンを検証するには、次の 3 つのパラメータを付けて所定の URL に POST リクエストを送ります。
パラメータ:
secret
: シークレットキーresponse
: クライアントサイドから送られたトークンremoteip
: (非必須)ユーザーの IP アドレス
URL:
https://developers.google.com/recaptcha/docs/verify
secret
は reCAPTCHA のコンソールの設定ページで取得できるシークレットキーです。
response
はクライアントサイドで取得したトークンです。
remoteip
はクライアントの IP アドレスです。 remoteip
は非必須です。
これを axios で行うには次のようにします。
const axios = require(`axios`)
const RECAPTCHA_VERIFY_URL = `https://www.google.com/recaptcha/api/siteverify`
let params = {
secret: `シークレット`,
response: `トークン`,
remoteip: `クライアント IP アドレス`,
}
recaptchaRes = await axios.post(RECAPTCHA_VERIFY_URL, undefined, {
params: params,
})
axios.post()
の第 2 引数が undefined
で、データは第 3 引数の params
キーを使って渡しているところがポイントです。
こうやっている理由は、 reCAPTCHA のエンドポイントには application/x-www-form-urlencoded
フォーマットでデータを送信する必要があるようなのですが、 axios.post()
を普通のやり方↓で使うと JSON リクエストになってしまうからです。
const axios = require(`axios`)
const RECAPTCHA_VERIFY_URL = `https://www.google.com/recaptcha/api/siteverify`
// このやり方は失敗します
let params = {
secret: `シークレット`,
response: `トークン`,
remoteip: `クライアント IP アドレス`,
}
recaptchaRes = await axios.post(RECAPTCHA_VERIFY_URL, params)
axios.post(url, params)
という形でデータを送ると、正しいデータを添えても「 secret
と response
が送られていませんよ」という旨のエラー↓が返ってきます。
原因がわからないとハマります。
'error-codes': [ 'missing-input-response', 'missing-input-secret' ]
ということで、まとめです。
- reCAPTCHA の検証のエンドポイントには
application/x-www-form-urlencoded
フォーマットでデータを送る必要がある( JSON だとパラメータを認識してくれず検証が失敗する) - axios はデフォルトでは JSON フォーマットでリクエストデータを送る(
application/x-www-form-urlencoded
フォーマットで送るには少し工夫が必要)
ちなみに、上の方法とは違いますが、 axios の公式 REAMDE でも application/x-www-form-urlencoded
フォーマットで POST リクエストを行う方法が紹介されているので、詳しく知りたい方はそちらもご覧ください。
参考
- Verifying the user's response | reCAPTCHA | Google Developers
- Using application/x-www-form-urlencoded format | GitHub - axios/axios
- node.js - reCAPTCHA - error-codes: 'missing-input-response', 'missing-input-secret' when verifying user's response (missing details on POST) - Stack Overflow
- node.js - Google Recaptcha not working with axios - Stack Overflow