Python Flaskで作成した登録画面にGoogleが提供しているreCAPTCHAを設置する方法をご紹介します。
今回、reCAPTCHAを実装することがメインなので、flaskの基礎的な知識(formの設置やtemplate,routesなどの説明は省略しますのでご了承ください。
GoogleのreCAPTCHAとは?
皆さんも一度はサイトやアプリで見たことがある「私はロボットではありません」と表示されているのがreCAPTCHAです。reCAPTCHAの役割は人間とボットを区別させるためでシステム歪んだ文字を読んで手入力したり、条件にふさわしい画像を複数選択する作業で見分けています。最近では画像を複数選択せずにチェックをするだけで人間とボットの区別ができるreCAPTCHAv3もあります。今回は、画像を複数選択するreCAPTCHAv2の実装方法を紹介していきますね。
先月、学内向けの団体とイベント共有サイト「KOMANEKO」をリリースし、スパム投稿を防止するために登録画面にreCAPTCHAの認証機能を設置しています。
KOMANEKO
KOMANEKOは団体情報とイベントを共有できる駒澤大学生向けのメディアサイトです。 KOMANEKOでは新入生に向けたサークルなどの団体情報を簡単に管理できるだけでなく、 部活、サークル、ゼミナールまたは個人が開催するイベントを簡単に共有し、Twitterなどでシェアすることができます。 グーグルマップやQRコード、ブックマーク機能を活用して、団体とユーザーを繋ぐ役割を果たします。
準備するもの
- Python 3.7
- pip (Python package installer)
- virtualenv
- Google アカウント
- reCHAPTERのアクセスキー
reCAPTCHAのアクセスキーを取得する
まずはreCAPTCHAのアクセスキーを取得するために下記アドレスにアクセスしてadmin consoleをクリック。
reCAPTCHA
We are excited to introduce reCAPTCHA v3, which helps you detect abusive traffic on your website without any user friction. It returns a score based on the interactions with your website and provides you more flexibility to take appropriate actions. See blog for more details.
続いてラベルやreCAPTCHAのタイプを選択します。今回は、画像を複数選択するreCAPTCHA2で実装します。
- ラベル→サイト名など
- reCAPTCHA→今回はreCAPTCHAv2を選択
- ドメイン→ローカルだと127.0.0.1、本番サイトだとfor-engineer.lifeとか
- オーナー→自分のアドレスを登録
利用条約に同意するにチェックをしたら送信を押下。ダッシュボードから設定画面を開くとサイトキーとシークレットキーが表示されます。このキーは後ほど使用します。
Virtualenvで仮装環境を作成する
続いてVirtualenvで仮装環境を作成していきます。コマンドからvirtualenvをインストールします。
pip install virtualenv
Googleフォルダを作成し、
mkdir Google #Googleフォルダを作成する。
cd Google
virtualenv reCaptcha #reCaptchaという名前の仮装環境を作成する。
Virtualenvを起動する
macの場合、source activate 環境名。windoesの場合はset activate 環境名で起動します。
source activate reCaptcha #mac
set activate reCaptcha #windoes
登録画面を作成し、reCAPTCHAを設置する
続いてflaskで登録画面を作成するため、以下の二つをインストールします。この二つをインストールすることでフォームのCSRF対策やファイルのアップロード、reCAPTCHAの実装ができます。
pip install Flask
pip install Flask-WTF
続いてapp.pyとform.pyファイルを作成します。
touch app.py form.py #app.pyとform.pyを作成する
登録画面を作成する
form.pyにコードを書き込んで登録画面を作成していきます。まずはフォーム画面に必要なものをflask_wtfとwtformからインポートします。
recaptchaの実装方法の確認がメインなのでformのコードの説明は省略します。今回、注目して欲しいのはflask_wtfからRecaptchaFieldをインポートしている点とRegisterFormにrecaptcha = RecaptchaField()を記述している点です。この二つを用意すれば、flaskで簡単にRecaptchaを設置することができます。
form.py
from flask_wtf import Form, RecaptchaField #flask_wtfからformとRecaptchaをインポートする
from wtforms import TextField, PasswordField, TextAreaField, StringField, validators
#フォーム画面に必要なフィールドを持ってくる。
class RegisterForm(Form):
name = StringField('ユーザー名', [validators.DataRequired(), validators.Length(max=255)])
password = PasswordField('パスワード', [validators.DataRequired(),validators.Length(min=8)])
email = StringField('メールアドレス', [validators.DataRequired(), validators.Length(min=6, max=35)])
recaptcha = RecaptchaField()
app.pyを作成する
続いてapp.pyを作成していきます。flaskからFlask, render_template, requestの三つとformからform.pyで作成したRegisterFormをインポートします。
app = Flask(name)の下にreCAPTCHAの設定画面で取得したアクセスキーを記述します。@app.route(‘/register’, methods=[‘GET’, ‘POST’]) の部分はrailsでいうroutesとcontrollerの役割を果たしています。登録画面のフォームボタンが押された際の処理とrender_templateはtemplateエンジンのhtmlをレンダリングします。今回はregister.htmlを呼び出します。
../reCaptcha/app.py
from flask import Flask, render_template, request,
from form import RegisterForm
app = Flask(__name__)
app.config['RECAPTCHA_USE_SSL']= False
#reCAPTCHAのアクセスキーを記述する
app.config['RECAPTCHA_PUBLIC_KEY']='enter_your_public_key'
app.config['RECAPTCHA_PRIVATE_KEY']='enter_your_private_key'
@app.route('/register', methods=['GET', 'POST'])
def register():
form = RegisterForm()
if form.validate_on_submit():
return "登録が完了しました"
return render_template("register.html", form=form)
if __name__ == '__main__':
app.run(port=5000, debug=True)
templateを作成する
続いてhtmlファイルを作成します。reCaptcha配下にtemplatesフォルダを作成し、その配下にregister.htmlを作成します。{{ form.recaptcha }}を記述することによってrecaptchaを表示させています。
// ../reCaptcha/templates/register.html
<html>
<head>
<title>ユーザー登録</title>
</head>
<body>
<h1>Register form</h1>
<form method="POST" action="{{ url_for('register') }}">
{{ form.csrf_token }}
{{ form.name.label }}
{{ form.name }}
<ul>
{% for error in form.name.error %}
<li style="coloured:red;">{{ error }}</li>
{% endfor %}
</ul>
{{ form.password.label }}
{{ form.password }}
{% for error in form.password.error %}
<ul>
<li style="coloured:red;">{{ error }}</li>
{% endfor %}
</ul>
{{ form.email.label }}
{{ form.email }}
<ul>
{% for error in form.email.error %}
<li style="coloured:red;">{{ error }}</li>
{% endfor %}
</ul>
{{ form.recaptcha }}
<input type="submit" value="利用規約に同意する">
</form>
</body>
</html>
ブラウザで表示されるか確認してみる
コマンドでpython app.pyを実行し、ブラウザで127.0.0.1:5000/registerにアクセスします。「フォーム画面と私はロボットではありません」が表示されれば実装完了です。