2021/11/13

RustでGoogle Recaptchaのtokenの検証

rustgoogle-recaptcha

概要

RustでGoogle Recaptcha v3のサーバー側の実装方法です。

Google recaptchaの検証方法については、こちらの記事(Verifying the user’s response)のまんまです。

client側で(javascriptなどを使って)発行した、recaptcha tokenをRust製のサーバー側で検証するやり方です。

panicbit/recaptcha-rsをほぼほぼまるコピーしたのですが、こちらのライブラリは最新のリリースバージョン(v0.5.0)ではtokioのバージョンが合わなかったため
自分用に作り直しました。(私はtokioのバージョン1を使っていますが、こちらのライブラリは0.2になっています。)

実装方法

依存ライブラリ

  • hyperをclientとして利用します。httpsのclient機能があれば十分です。
[dependencies.http]
version = "0.2"

[dependencies.hyper]
version = "0.14"
features = ["client"]

[dependencies.hyper-rustls]
version = "0.22.1"

実際の検証

use http::Request;
use hyper_rustls::HttpsConnector;
use std::io::Read;

let secret = "your-google-recaptcha-api-secret";
let response = "recaptcha-token-retrieved-by-client-process";
let remote_ip = Some("123.123.123.123");  // Client ip address i.e. get from 'X-Real-IP' http header.

let mut query = format!("secret={}&response={}", secret, response);
if let Some(remote_ip) = remote_ip {
    query = query + &format!("&remoteip={}", remote_ip);
}
let uri = format!("https://www.google.com/recaptcha/api/siteverify?{}", query);
let request = Request::builder()
    .method("GET")
    .uri(uri)
    .body(hyper::Body::empty())
    .unwrap();
let client = hyper::Client::builder().build(HttpsConnector::with_native_roots());
let response = client.request(request).await?;
 let mut response_body = String::new();
hyper::body::aggregate(response.into_body())
    .await?
    .reader()
    .read_to_string(&mut response_body)?;
// 受け取ったresponse_bodyはjson形式なので、deserializeして利用すると便利です。

おまけ

種々のプロジェクトで流用できるようにライブラリ化しています。

crate自体は公開してないですが、kumanote/recaptcha-rsとしてgithub上にソースコードを公開しています。

以上です。