目次
こんにちは。sinyです。
この記事ではDjangoでソーシャル連携認証を実装する手順について解説しています。
具体的にはdjango-allauthというモジュールを使って実装していきますが、デフォルトのデザインがシンプルすぎてそのまま実際のサービスで利用するのは厳しいので、以下の動画のようなデザインにカスタマイズするところまで簡単に解説します。
本記事で紹介しているDjangoプロジェクトは以下のGITリポジトリで公開していますのでご自由にお使いください。
方針
この記事では以下のような仕様でソーシャル認証機能を実装することとします。
- ソーシャル認証はTwitterとGoogleの2種類用意する。
- 通常の認証機能(メールアドレス+パスワード)も用意する。
- 新規登録時は指定のメールアドレスに確認メール配信&メールの登録確認を行う。
仮想環境の作成
まず最初に仮想環境を作成していきます。
今回はdjango-allauthという名称で仮想環境を作成し、アクティベートします。
python -m venv django-allauth django-allauth\scripts\activate
モジュールのインストール
続いてDjango本体とdjango-allauthモジュールをインストールします。
pip install django pip install django-allauth
この記事では以下のバージョンで動作を確認しています。
モジュール | バージョン |
django | 3.0.6 |
django-allauth | 0.41.0 |
Djangoプロジェクト、アプリの作成
django-allauthフォルダを作って以下のコマンドし、Djangoプロジェクトとアプリケーションを作成します。
cd django-allauth django-admin startproject config . python manage.py startapp accounts
ここは特に問題ないでしょう。
settings.pyのカスタマイズ
settings.pyで各種設定を行っていきます。
INSTALLED_APPS
django-allauthパッケージをINSTALLED_APPSに追加する。
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'django.contrib.sites', #add 'allauth', #add 'allauth.account', #add 'allauth.socialaccount', #add 'allauth.socialaccount.providers.twitter', #add 'allauth.socialaccount.providers.google', #add 'accounts', #add ]
なお、allauth.socialaccount.providers.<プロバイダ名>は認証プロバイダ毎に設定が必要です。
今回はTwitterとGoogleの2つを追加しています。
その他に指定できるプロバイダーについては下記リンクに情報があります。
テンプレートの設定
つづいて、Djangoのテンプレートを配置する場所を設定します。
変更前
'DIRS': [],
変更後
'DIRS': [os.path.join(BASE_DIR, 'templates')],
これでdjangoプロジェクトフォルダ直下のtemplatesフォルダがテンプレートのベースフォルダになります。
静的ファイルの設定
続いてcssファイル等の静的ファイルを配置する場所をSTATIC_ROOTパラメータで指定します。
STATIC_ROOT = os.path.join(BASE_DIR, 'static_for_deploy')
これでDjangoプロジェクトフォルダ直下のstatic_for_deployフォルダが静的ファイルの集約場所になります。
なお、デフォルトではアプリケーションフォルダ直下のstaticフォルダ配下が静的ファイルの格納場所です。
メールアドレスとパスワードで認証するためのカスタマイズ
デフォルトだとユーザ名+パスワードで認証する形になっているので、メールアドレス+パスワードで認証できる設定に変更します。
以下の通りAUTHENTICATION_BACKENDSパラメータを設定します。
AUTHENTICATION_BACKENDS = ( 'django.contrib.auth.backends.ModelBackend', #default 'allauth.account.auth_backends.AuthenticationBackend', # django-allauth を追加 )
続いて以下のパラメータを設定します。
パラメータの意味はコメント欄を参照いただければ分かると思います。
ACCOUNT_AUTHENTICATION_METHOD = 'email' # email+パスワード認証方式を指定 ACCOUNT_USERNAME_REQUIRED = False # ユーザ名を利用しない設定にする SITE_ID = 1 #django-allauthを利用する際に必要な設定 LOGIN_REDIRECT_URL = 'home' # ログインURLの設定 LOGIN_URL = '/accounts/login/' #ログイン画面を何処にするかの設定 ACCOUNT_LOGOUT_REDIRECT_URL = '/accounts/login/' #ログアウトリダイレクトの設定 ACCOUNT_EMAIL_VERIFICATION = 'mandatory' #ユーザ登録確認メールを送信する ACCOUNT_EMAIL_REQUIRED = True #メールアドレスを必須項目に指定 EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' #コンソール上にメッセージを表示
言語関連の設定
言語とタイムゾーンを以下の通り変更しておきます。
LANGUAGE_CODE = 'ja' TIME_ZONE = 'Asia/Tokyo'
urls.pyの設定
プロジェクトフォルダ直下のurls.pyでURLパターンの設定を行います。
config/urls.py
from django.contrib import admin from django.urls import path, include #includeを追加 from django.views.generic import TemplateView #追加 urlpatterns = [ path('admin/', admin.site.urls), path('', TemplateView.as_view(template_name='home.html'), name='home'), #追加 path('accounts/', include('allauth.urls')), #追加 ]
以下は、認証が完了した後にTOP画面(home.html)にリダイレクトする設定です。
path('', TemplateView.as_view(template_name='home.html'), name='home'), #追加
以下でdjango-allauthのurls.pyの定義をインクルードしています。
path('accounts/', include('allauth.urls')), #追加
管理者ユーザの作成とマイグレーション
ここで一旦管理者ユーザの作成とマイグレーションを行います。
python manage.py makemigrations python manage.py migrate python manage.py createsuperuser
開発サーバを起動してadminサイトにログオンできることを確認しておきましょう。
python manage.py runserver
以下のような画面が表示されればOKです。
OAuth アプリケーションの登録
今回はtwitterとGoogleにOAuth認証するので、各プロバイダサイトでOAuth アプリケーションを登録する必要があります。
詳細手順は他サイトを見ていただければ分かると思いますので、ポイントだけ記載しておきます。
Googleの場合は以下のサイトから登録できます。
登録すると「クライアントID」と「クライアントシークレット」が発行されるので控えておきます。
Twitterの場合は以下のサイトから登録できます。
登録すると「API key」と「API secret key」が発行されるので控えておきます。
なお、callbackURLに設定する値はそれぞれ以下のようにします。
http://localhost:8000/accounts/twitter/login/callback/
http://localhost:8000/accounts/google/login/callback/
詳細手順については以下のサイトが参考になりました。
Social applicationsの設定
先ほど発行したキーを使ってDjangoのadminサイト上で認証プロバイダーの登録を行います。
adminサイトにログオンしたら「外部アカウント」の「Social applications」をクリックします。
「SOCIAL APPLICATIONを追加」ボタンを押して以下の通りプロバイダー情報を追加します。
「プロバイダー」からTwitter or Googleを各々選択して必要な情報(名前、Client ID、Secret Key)を入力します。
Siteも以下の通り登録しておきます。
テンプレートファイルの作成
ログオン後に表示されるhome.htmlファイルを作成しておきます。
tempates\home.html
<!doctype html> <html lang="ja"> <head> <meta charset="utf-8"> </head> <body> {% if user.is_authenticated %} <h5> ログオンユーザ名: {{ user.get_username }} さん<br> メールアドレス: {{ user.email }}<br> セッション開始時刻: {{ user.last_login }} </h5> {% endif %} </body> </html>
以上でソーシャル認証の基本設定は完了です。
http://localhost:8000/accounts/login/にアクセスすると以下のようなログオン画面が表示されます。
赤枠の部分をクリックするとソーシャル認証することができます。
試しにtwitter認証をクリックすると以下のような画面が表示されます。
初回アクセス時は確認用のメールアドレスを入力して「ユーザ登録」ボタンを押す必要があります。
「ユーザ登録」ボタンを押すと以下の画面が表示されます。
今回はコンソール画面上にメッセージを飛ばすように設定しているので、コンソール上に表示されている赤枠部分のURLをブラウザにコピペしてアクセスしましょう。
メールアドレスを確認して「確認する」ボタンを押します。
すると最初のログオン画面に戻るので、再度Twitter認証ボタンを押すと自動的に認証が走りTOP画面(home.html)が表示されます。
今回は以下のように「ユーザ名、メールアドレス、セッション開始時刻」を表示させるだけの単純なTOPページにしています。
以上でソーシャル認証の実装は完了していますが、上記のとおりデザインがしょぼすぎてこのまま実サービスでは利用できないので、見た目を整えていきます。
デザインのカスタマイズ
CSSファイルの準備
accountsアプリケーションフォルダ直下にstatic\cssフォルダを作成して以下のstyle.cssファイルを配置します。
@import url(https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css); @import url(http://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css); body { background-color: #f0f3f5; font-family: 'Roboto'; } .box { background-color: #fff; padding: 35px 40px; margin-top: 60px; /*Remove, its example*/ box-shadow: 0 8px 17px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); } .input-group { margin: 5px 0px; } .addon-google { background-color: hsl(345, 83%, 36%); border: none; border-radius: 2px 0px 0px 2px; color: #fff; } .btn-google, .btn-google:hover { background-color: hsl(345, 94%, 42%); color: #fff; border-radius: 0px 2px 2px 0px; font-size: 15px; } .addon-twitter { background-color: #00c6e9; border: none; border-radius: 2px 0px 0px 2px; color: #fff; } .btn-twitter, .btn-twitter:hover { background-color: #00d7fa; color: #fff; border-radius: 0px; font-size: 15px; } .btn-primary { border-radius: 2px; background-color: #23a9f6; border-color: #23a9f6; margin: 10px 0px; } p { color: #aebbcb; } a { color: #23a9f6; } .divider-form { border: 1px solid #EBEFF1; margin: 15px -40px 10px; } label { text-transform: uppercase; color: #bdc7d4; } strong { color: #95a5bb; } .form-control { background: none; height: 40px; border: none; border-radius: 0px; box-shadow: none; color: #8b9eb6; padding: 0px; } .form-control:focus { box-shadow: none; } div.field { margin-top: 30px; } div.field > span.helptext { font-size: 14px; color: #999; } div.field > label { display: block; } div.field > input, div.field > textarea, div.field > select, div.field > button { width: 100%; padding: 6px 12px; box-sizing: border-box; border-radius: 4px; border: solid 1px #999; } .alert-message { background-color: red; color:rgb(255, 255, 255); } .info-message { background-color: rgb(108, 116, 236); color:white; }
テンプレートファイルの上書き
django-allauthモジュールでデフォルトで使われる認証画面関連のテンプレートファイルLib\site-packages\allauth\templates配下に格納されています。
このテンプレートを上書きすることでデザインをカスタマイズしていきますが、上記パスにあるテンプレートを直接修正するのはあまりよくないので、以下の方法で設定を上書きします。
Djangoではアプリケーションで使われているテンプレートを上書きしたい場合、templatesフォルダ配下にアプリケーションと同じ名称のフォルダを作成し、同じHTMLファイル名を配置することで上書きすることができます。
実際は上書きというよりテンプレートの参照先を切り替えています。
Djangoにおけるテンプレートファイルの探索順序については以下の記事がわかりやすく纏められています。
以下のようにtemplatesフォルダ配下にフォルダを生成します。
templates
├─account #add
│ └─email #add
└─socialaccount #add
└─snippets #add
このフォルダ構成はLib\site-packages\allauth\templates配下のフォルダ構成に合わせて作成します。
今回は以下のテンプレートファイルをカスタマイズします。
※ファイル数が多いのでHTMLの詳細についての説明は割愛します。
カスタマイズしたファイルはGITHUBリポジトリにありますので適宜ダウンロードしてください。
- base.html(共通テンプレート)
- signup.html(サインアップ画面)
- password_reset_from_key.html(パスワードリセット)
- password_reset.html(パスワードリセット)
- login.html(ログオン画面)
- logout.html(ログアウト画面)
- email_confirm.html(Email確認画面)
- email_confirmation_message.txt(Email確認メッセージ)
- email_confirmation_subject.txt(Email確認メッセージのタイトル)
- password_reset_key_message.txt(パスワードリセットメッセージ)
- password_reset_key_subject.txt(パスワードリセットメッセージのタイトル)
- authentication_error.html(ソーシャル認証エラー発生時の画面)
- signup.html(ソーシャル認証サインアップ時の画面)
静的ファイルの配信
以下のコマンドを実行して静的ファイルをstatic_for_deployフォルダに集約させます。
python manage.py collectstatic
以上でカスタマイズは完了です。
http://127.0.0.1:8000/accounts/login/ にアクセスすると以下のようなデザインに変更されます。
以上、「Djangoソーシャル認証の実装手順」でした。