仮想通貨Monacoin(モナコイン)ってなに?

モナーコインの普及を切に願うサイトです

【faucet開発】フロントページにreCAPTCHA認証を設置する

time 2017/05/21

【faucet開発】フロントページにreCAPTCHA認証を設置する

sponsored link

faucetでアクセス制御する理由

faucetアプリは、サイトに訪問してくれたユーザへMONAを配布するサービスです。

ユーザとしてはより多くMONAを得たいと考えているため、一部の不正なユーザは連続で何回もアクセスするような悪意あるプログラムを使ってコインをかすめ取ろうと考えています。一方、サイトの運営側としては多くの人に少しずつMONAを配布して世の中にMONAを広めたい、より多くの人にMONAを知ってもらいたいと考えているため、特定個人に大量にMONAを配布するわけにはいきません。

そのため、世に普及している多くのfaucetアプリでは、様々なアクセス制御策が施されています。例えば一定時間毎にしか出金できないようにする「時間」の制御であったり、いまサイトにアクセスしてきているユーザが人なのかプログラム(Bot)なのかを制御する認証制御であったりです。

さて、前置きが長くなりましたが、今回設置するreCAPTCHA認証とはBotによる不正なアクセスを排除するためにgoogleが開発した認証処理のことです。よく見るこれです↓

認証処理の結果がここに表示されます。

httpdとphpのセットアップ

前提として、前回monacoindサーバをセットアップした環境(AmazonLinux)で構築していきます。今回は、webサーバにhttpd2.4(apache2)を使い、プログラム側ではphp7.0を使って認証処理を実装します。httpd24関連とphp70関連のパッケージをまるっとインストールします。

インストール

起動

続いて、とりあえずデフォルト設定のまま起動します。カスタマイズしたい方は各自適宜変更してください。また、monacoindと同様にサーバ再起動時にも自動でサービス起動をするようにしておきます。

アクセス確認

この時点で、ブラウザからサーバの pubric ip にアクセスするとhttpdのテストページが表示されるはずです。pubric ipとは、AWSからインスタンスに割り当てられるグローバルIPのことで、管理画面から確認できます。

PubricIP

今回の例だとブラウザで http://54.250.229.141/ にアクセスすると下のようなテストページが表示されます。

test page

認証ページを用意

reCAPTCHAを設置するための認証ページを用意します。まだプログラムを実装しないので、とりあえず画面だけ作ります。

これで http://54.250.229.141/ もしくは http://54.250.229.141/index.php にアクセスすると今作成した画面が表示されます。ここまできたらいったんサーバ側の設定は置いておき、reCAPTCHAの利用登録をします。

reCAPTCHAの利用登録

reCAPTCHAを使用するには、googleで利用登録する必要があります。登録すると発行される sitekey 及び secretkey を使って、いま作成したwebアプリとgoogleの認証ロジックを連携することでBot判定が可能となります。

1. googleアカウントの取得

まず、googleのアカウントを用意します。おそらくfaucetをアプリを作ろうと思ってる方の多くはgoogleアカウントをお持ちだと思いますので、ここの手順は省略します。まだお持ちでない方は、 アカウントの作成ページ から必要事項を入力して作成してください。

次からの手順は、googleアカウントでログインしている前提で進めます。

reCAPTCHA

reCAPTCHAのサイトにアクセスして右上の「Get reCPATCHA」をクリックします。

reCAPTCHAの設定

今回は以下のように入力しました。

Label : sample
Choose the type of reCAPTCHA : reCAPTCHA v2
Domains : 52.197.85.73 (reCAPTCHAを設置するサーバのIPかドメイン)

「Accept the reCAPTCHA Terms of Service」にチェックを入れたら右下のRgisterをクリックします。正常に処理が完了すると、下のような画面が表示されます。この情報を使ってアプリケーションに認証処理を実装します。

reCAPTCHA v2

secretkeyは漏洩すると不正アクセスの原因となります。絶対に他の人に知られないように管理してください。

reCAPTCHAの実装

では、先ほど作成した index.php にreCAPTCHAを実装していきます。まずはプログラムをphpを組み込む前に、データを送信するためにフォームを作成します。

認証フォームの作成

先頭に + を記している6行目から12行目が今回追記した部分です。7行目と9行目は、先ほどreCAPTCHAの利用登録をした際にsitekeyやsecretkeyの下に表示されていたコードです。

7行目ではデータの送信先を指定し、9行目ではsitekeyを指定しています。このsitekeyにより、google側ではこのデータがどのアカウントの所有するreCAPTCHAから送られてきたデータなのかを判別しています。
8,10,11行目ではデータを送信するためのフォームをhtmlで記述しています。reCAPTCHAはPOSTメソッドに対応していませんので、必ずGETを指定します。

あらためてブラウザからアクセスするとこんな画面になっています。
reCAPTCHA画面

認証してみる

では、ブラウザのほうで実際に認証処理を動かして見ましょう。チェックをつけて送信ボタンをすと、GETリクエストなので結果がブラウザのURL欄に返ってきているはずです。例えば、今回の場合はこんなデータが返ってきました。

‘g-recaptcha-response=’ の後に続く文字列がgoogleから返ってきたレスポンスデータです。このレスポンスデータ自体には、今回の認証が成功だったのか、失敗だったのかの判定結果は含まれていません。このレスポンスデータを使用して、再度アプリケーションがgoogleへ問い合わせをすることにより、認証結果を得ます。この問い合わせの際に、先ほど他の人には知られてはいけないと書いたsecretkeyを使用します。サーバの管理者しか知らないsecretkeyでのみ、正しい認証結果を得られる仕組みにすることで、一般ユーザからの不正なアクセスを防ぐようにしています。

認証結果を取得する仕組み

認証結果は、https://www.google.com/recaptcha/api/siteverify に対して secretkey とレスポンスデータをPOSTするとJSON形式で返ってきます。

例えば curl で投げるとこんな感じです。

{secretkey}と{レスポンスデータ}は適宜自分の環境にあった値を入れてください。

認証が成功だった場合は↓のような値が返ります。

失敗だった場合は↓のような値が返ります。

つまり、アプリ側ではsuccessの値が true なのか false なのかで判定をすれば良さそうです。おさらいすると、reCAPTCHAによる認証処理は以下の流れです。

  1. ユーザがフォームから画像を撰択して送信ボタンを押す
  2. アプリはそのデータをgoogleに送る
  3. googleはデータの判定をして、アプリにレスポンスデータを返す
  4. アプリはレスポンスデータとsecretkeyをgoogleに送る
  5. googleはアプリに認証結果を返す
  6. アプリは認証結果の成否によってユーザに次の画面を返す

認証処理の実装

仕組みがわかったところで、アプリに認証ロジックを実装していきます。今回は、認証に成功したら「成功!!!」、失敗したらエラーコードを画面に表示する処理を作ってみます。先ほどフォーム画面を作成したindex.phpにphpの処理を追記します。

1行目から31行目と40行目から53行目までが追記部分です。3行目でレスポンスデータの有無を判定し、有であれば認証結果をgoogleに問い合わせます。

7行目ではsecretkeyを定義しています。今回は横着してコードにベタ書きしてますが、セキュリティの観点から言えば別の設定ファイルなりDBなりに保存しておいて都度参照しに行く形が望ましいです。なぜなら、ベタ書きしたことを忘れたままgithubのようなソースコードを参照できるサイトに公開してしまうと、世界中にsecretkeyが知れ渡ることになるからです。

10行目では認証結果の問い合わせ先となるgoogleのURL(エンドポイント)を指定し、13行目では問い合わせに使うクエリを定義しています。クエリは、エンドポイントとレスポンスデータとsecretkeyを連結しています。

実際に問い合わせを行う処理が16〜21行目です。接続用のオブジェクトを作成して、クエリの結果($rtn_recapcha_json)を受け取ってからオブジェクトを削除しています。

24行目では、受け取った検証結果の文字化けを回避するためにエンコードしています。基本的に返ってくるデータは英数字だと思うのでもしかしたらここの処理は不要かもしれません。

27〜29行目では、受け取ったデータのうち必要な部分のみを取り出しています。今回は、認証結果とエラーコードのみを取得しています。

最後に、40〜53行目で結果を画面に表示する処理を記述しています。認証結果がtrueなら「成功!!!」、trueでなければエラーコードを返します。

動作確認

普通にボタンをクリックするだけでは基本的に成功しか返ってきません。エラーの確認をするには、例えばURL上のレスポンスデータの部分を適当に変えて叩いてみる方法があります。もしくは、認証成功のタイムアウト(有効期間)は2分間のみですので、「認証成功!!!」の画面を2分後に更新してみてもエラーの確認ができます。この記事の頭にサンプル版を設置しているので試して見てください。

おわり

世の中のfaucetアプリを見ていると、多くのサイトでreCAPTCHA認証が使われています。1BTCあたり25万円ともなればそりゃBotで取りたくなる人も出てくるのでしょう。reCAPTCHAを使えば100%安全というわけではありませんが、自分で認証ロジックをあれこれ悩むよりかは遥かに簡単に実装できると思います。faucetアプリを作ってる方は是非導入してみてください。

sponsored link

down

コメントする




挨拶

プロフィール

ああああ

ああああ

ドラクエを愛してやまない33歳です。11をPS4でやるか3DSでやるか悩み中。

最近のコメント

    イイネと思ったら投げ銭を

    

    sponsored link