DjangoでGoogleのOAuth2 ログイン認証とログアウトの設定方法

GoogleやFacebook、GitHubアカウントでのログイン機能は便利ですからね。DjangアプリでOAuth2ログイン認証を取り入れたく、実装方法を調べました。

かなり手こずったので、忘れないようにメモします。

social-authプラグインのインストール

Python Social Authというオーガナイゼーション(GitHub上のグループ)にDjango向けのソーシャルログイン機能をサポートするプラグインが提供されていましたので、これを使います。

https://github.com/python-social-auth/social-app-django

pip install social-auth-app-django

セッティング

まずsettings.pyに色々設定します。↓

アプリケーション登録

social_django の一文をsettings.pyの__INSTALLED_APPSに追記します。

INSTALLED_APPS = (
    ...
    'social_django',
    ...
)

テンプレートコンテキストの追記

バックエンドと関連データを扱うためのコンテキストプロセッサを TEMPLATES に追記します。

TEMPLATES = [
    {
        ...
        'OPTIONS': {
            ...
            'context_processors': [
                ...
                'social_django.context_processors.backends',
                'social_django.context_processors.login_redirect',
                ...
            ]
        }
    }
]

認証用バックエンドの設定

認証用に使いたいバックエンドをsettings.pyに追記します。

AUTHENTICATION_BACKENDS = (
 'social_core.backends.open_id.OpenIdAuth',  # for Google authentication
 'social_core.backends.google.GoogleOpenId',  # for Google authentication
 'social_core.backends.google.GoogleOAuth2',  # for Google authentication
 'social_core.backends.github.GithubOAuth2',  # for Github authentication
 'social_core.backends.facebook.FacebookOAuth2',  # for Facebook authentication
 'django.contrib.auth.backends.ModelBackend',
)

ログインURLとリダイレクト先の指定

ログインURLとログイン認証後のリダイレクト先、ログアウト後のリダイレクト先を指定します。

LOGIN_URL = 'login'
LOGIN_REDIRECT_URL = 'home'
LOGOUT_REDIRECT_URL = 'home'

DBの設定

Djangoのバージョンが1.7以降の場合はマイグレーションを実施します。

python manage.py migrate

PostgreSQLを使う場合は組み込みのJSONBフィールドという物を使うのが良いそうなので、settings.pyに追記します。

SOCIAL_AUTH_POSTGRES_JSONFIELD = True

OAuthクレデンシャルの設定

これは採用するバックエンドによるので詳細は省きますが、Googleの場合は次のようにクレデンシャル情報を環境変数に設定します。

SOCIAL_AUTH_GOOGLE_OAUTH2_KEY ='xxxxx'  #Paste CLient Key
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = 'xxxxx' #Paste Secret Key

クレデンシャル情報はこちらから取ってきます。https://console.developers.google.com

APIキーに認証されたリダイレクト先URIを登録する必要があるのですが、ローカル環境の場合は次のようにします。

http://localhost:8000/auth/complete/google-oauth2/

諸事情でlocalhostを使えない時は、適当なドメイン名を認証リダイレクト先として指定し、ローカルPCのホストを書き換えてあげると良いです。

実装

PATHの設定

urls.pyを次のように設定します。

from django.urls import path, include
from django.contrib.auth import views as auth_views
from . import views

urlpatterns = [
    path('', views.home, name='home'),
    path('auth/', include('social_django.urls', namespace='social')), # <- 追記
    path('logout/', auth_views.LogoutView.as_view(), name='logout'), # <- 追記
]

ページ遷移をしたくないので、ログイン用、ログアウト用のページは用意しませんでした。

テンプレート側にリンクを設置

ログインボタンを用意します。Google OAuth2を使う場合は↓。

<a href="{%!u(MISSING)rl 'social:begin' 'google-oauth2' %!}(MISSING)">Googleアカウント</a>

ログイン前後でリンクの表記を変えたい場合は、例えば次のようにif文で分岐させたりします。

{%!i(MISSING)f user.is_authenticated %!}(MISSING)
<span>Hello, {{ user.username }}</span>
<a class="nav-link" href="{%!u(MISSING)rl 'logout' %!}(MISSING)">ログアウト</a>
{%!e(MISSING)lse %!}(MISSING)
<a id="login-btn" class="nav-link" href="#" data-toggle="modal" data-target="#login-form-modal">ログイン</a>
{%!e(MISSING)ndif %!}(MISSING)

まとめ

↓いい感じに実装できました。やったね!次は普通のメアド登録機能も追加しなきゃー。