django-allauthを利用したソーシャルログイン機能の実装

先日Django Sprintに参加させて頂きました。
Djangoに関する様々な活動をされてる方々と接する事ができたので、とても有意義な時間を過ごせました。
私の方は、django-allauthに関する調査を行いましたので今回はその内容をご紹介させて頂きたいと思います。

django-allauthとは?

https://github.com/pennersr/django-allauth

django-allauthを利用するとFacebooktwitter、GitHubなどのサードパーティ製の認証システムを利用して
ログインすることができるようになります。

対応メディアは下記の通りです。

上記のメディア以外でもログイン処理を実装したクラスを追加する事で拡張していくことが可能です。
またその他、下記の機能に対応しています。

  • Signup of both local and social accounts (ローカルアカウント、シャールアカウント両方に対応)

  • Connecting more than one social account to a local account
    (ローカルアカウントに1つ以上のソーシャルアカウントを紐づける。)

  • Disconnecting a social account -- requires setting a password if only the local account remains
    ( ソーシャルアカウントとの紐付けの解除)
  • Optional instant-signup for social accounts -- no questions asked
  • E-mail address management (multiple e-mail addresses, setting a primary) (メールアドレスの管理)

  • Password forgotten flow(パスワードを忘れた場合の確認機能)

  • E-mail address verification flow(メールアドレスの確認機能)

今回はDjanogのプロジェクトを作成し、django-allauthを利用して
各ソーシャルメディアでログイン処理が出来るまでを試してみました。

仮想環境の構築

まずはプロジェクト用の仮想環境を構築します。

mkvirtualenv django-allauth-sample

必要なモジュールのインストール

pip install django
pip install django-allauth

Djangoのプロジェクトの作成

django-admin.py startproject django_allauth_sample

/etc/hostsの変更

ログイン認証時のコールバック用に、/etc/hostsに下記の記述を追加します。

127.0.0.1 local-test.com

テスト起動

cd django_allauth_sample/
python manage.py runserver

Validating models...
0 errors found
Django version 1.4.5, using settings 'django_allauth_sample.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
[22/Feb/2013 21:26:38] "GET / HTTP/1.1" 200 1972

下記のURLをブラウザで開いて表示されていればOKです。
http://local-test.com:8000/

Djangoに関する基本的な設定の追加、編集

下記の記述を参考にsettings.pyを変更します。

BASE_DIRの設定

settings.pyの上部に記述を追加します。

import os
BASE_DIR = os.path.dirname(os.path.abspath(__file__))

DBに関する記述を変更

今回はsqlite3を使用するので、下記のように修正します。

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': os.path.join(BASE_DIR, '../../db/sample.db'),     # Or path to database file if using sqlite3.
        'USER': '',                      # Not used with sqlite3.
        'PASSWORD': '',                  # Not used with sqlite3.
        'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
    }
}

タイムゾーンの変更

TIME_ZONE = 'Asia/Tokyo'

言語コードの変更

LANGUAGE_CODE = 'ja'

TEMPLATE_DIRSの設定

今回はテンプレートファイルを/templates/配下に設置するので
その設定を追加します。

TEMPLATE_DIRS = (
    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
    os.path.join(BASE_DIR, 'templates/'),
)

django-allauthに関する設定の追加、編集

django-allauthのドキュメントを参考に、 各種動作に必要なsetteings.pyの変更をします。

TEMPLATE_CONTEXT_PROCESSORSの変更

TEMPLATE_CONTEXT_PROCESSORSの内容を設定します。

TEMPLATE_CONTEXT_PROCESSORS = (
    'django.core.context_processors.debug',
    'django.core.context_processors.i18n',
    'django.core.context_processors.media',
    'django.core.context_processors.static',
    'django.contrib.auth.context_processors.auth',
    'django.contrib.messages.context_processors.messages',
    'django.core.context_processors.request',

    # 追加
    "allauth.account.context_processors.account",
    "allauth.socialaccount.context_processors.socialaccount",
)

INSTALLED_APPSの変更

INSTALLED_APPSの設定を変更します。
管理画面用のadmin、allauthの動作に必要なアプリケーション、
各種ログインに利用するソーシャルメディアのアプリケーションを有効にします。

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    # Uncomment the next line to enable the admin:
    'django.contrib.admin',
     
    # Uncomment the next line to enable admin documentation:
    # 'django.contrib.admindocs',

    'allauth',
    'allauth.account',
    'allauth.socialaccount',

    # ... include the providers you want to enable:
    'allauth.socialaccount.providers.twitter',
    'allauth.socialaccount.providers.facebook',
    'allauth.socialaccount.providers.github',
    #'allauth.socialaccount.providers.linkedin',
    #'allauth.socialaccount.providers.openid',
    #'allauth.socialaccount.providers.persona',
    #'allauth.socialaccount.providers.soundcloud',
    #'allauth.socialaccount.providers.stackexchange',

)

AUTHENTICATION_BACKENDSの設定

allauthの認証システムを利用するので、記述を追加します。

AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.ModelBackend',
    "allauth.account.auth_backends.AuthenticationBackend",
    )

SOCIALACCOUNT_PROVIDERSの設定

各ソーシャルメディア用の具体的な設定(スコープ等)は、
SOCIALACCOUNT_PROVIDERSに設定していきます。

SOCIALACCOUNT_PROVIDERS = {
    'facebook': {
        'SCOPE': ['email', 'publish_stream'],
        'AUTH_PARAMS': {'auth_type': 'reauthenticate'},
        'METHOD': 'oauth2',
        'LOCALE_FUNC': lambda request: 'ja_JP'
    },
    'github': {
        'SCOPE': ['user:follow', 'gist']
    }
}

LOGIN_REDIRECT_URLの設定

ログインした後、デフォルトで表示するページのURLを指定します。

LOGIN_REDIRECT_URL = '/'

参考URL
https://docs.djangoproject.com/en/1.4/ref/settings/

テーブルの作成

テーブルを作成します。

python manage.py syncdb

urls.pyの設定

管理画面用、allauth用、indexページ用の設定を追加します。

from django.conf.urls import patterns, include, url

# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',

    # Examples:
    # url(r'^$', 'django_allauth_sample.views.home', name='home'),
    # url(r'^django_allauth_sample/', include('django_allauth_sample.foo.urls')),

    # Uncomment the admin/doc line below to enable admin documentation:
    # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),

    # Uncomment the next line to enable the admin:
    url(r'^admin/', include(admin.site.urls)),
    url(r'^accounts/', include('allauth.urls')),
    url(r'^$', login_required(direct_to_template), {'template': 'index.html'}),
    )

各種ソーシャルメディアのアプリケーションの登録

ログインに使用するソーシャルメディアのアプリケーションを登録します。
詳細は割愛しますがFacebookTwitter、GitHubの各アプリ登録ページから登録することが可能です。

参考URL

今回はテスト用ドメインをlocal-test.comとしたので、
各コールバックURLは下記のように設定しました。

http://local-test.com:8000/accounts/facebook/login/callback/ (Facebook)
http://local-test.com:8000/accounts/twitter/login/callback/ (Twitter)
http://local-test.com:8000/accounts/github/login/callback/ (GitHub)

登録したアプリケーションの追加


サンプルアプリケーションに上記で登録したアプリケーションを追加していきます。

  • 管理画面にログイン(http://local-test.com:8000/admin/)
  • [Social apps]のリンクをクリック
  • [social app を追加]をクリック
  • 追加画面になるので、各アプリケーションを追加
    (Client idとSecretはメディアによって名称が違います。)
  • Providerを選択
  • Nameを入力
  • Client idを入力
  • Secretを入力
  • Sitesを選択

ログイン

下記のURLにアクセスするとログイン画面が表示され、
各ソーシャルメディアのアカウントを利用してログインする事が可能になります。

f:id:checkpoint:20130226134254p:plain

  • 注 Emailの設定を適切に設定しないと、signup時の確認用のメールが送信される際にConnection refusedのエラーが発生します。

確認用のEmailを送信しないようにするには、下記のように設定します。

ACCOUNT_EMAIL_VERIFICATION = 'none';

まとめ

今回はdjango-allauthを利用した、ソーシャルログイン機能の実装について書かせて頂きました。
django-allauthを利用すると非常に簡単にソーシャルログイン機能を追加する事ができるので、
今後アプリケーションを作成する際に利用を検討してみようかと思います。
django-allauthには非常にたくさんの機能があるのですが、まだまだほんの一部しか紹介しきれておりません。
詳細はdjango-allauthのドキュメントを参照して頂ければと思います。

今後は同様のライブラリにdjango-social-authというものがあるので、
そちらのライブラリ使い方や、比較を書いていきたいと思います。

参考リンク

今回の記事を書く際に参考にしたサイトです。

サンプルソース

今回の記事を作成する際に書いたサンプルソースを公開致します。
下記のリンクより閲覧可能です。
(BootstrapやjQueryを利用して若干デザインを見やすいように修正しています。)