django-allauth
目次

概要

Integrated set of Django applications addressing authentication, registration, account management as well as 3rd party (social) account authentication.

主な機能

  • ログイン

  • ログアウト

  • パスワード変更

  • パスワード再設定

  • ユーザー登録

  • ユーザー登録時にメールを送信して登録確認

  • メールアドレスとパスワードでログイン

  • ログイン失敗回数制限

  • ソーシャル連携認証

  • テンプレートも用意してくれている

GitHub とソーシャル連携認証してみる

手順

  1. GitHub に OAuth アプリケーションを登録する

    • https://github.com/settings/developers > OAuth Apps > Register a new OAuth application

      /images/django/allauth/00_register-oauth-application.png
      • Authorization callback URL: サービスプロバイダが認可コードを返した後に Web アプリ側にリダイレクトするための URL

        • django-allauth を使う場合はサービスプロバイダによって異なる

        • サービスプロバイダごとに異なるビュー関数が用意されているため

    • 設定値は後から Update できるよ

  2. Admin サイトで GitHub とソーシャル連携するために初期データを登録する

    # django-allauth をインストールする
    $ pip3 install django-allauth
    
    # マイグレーション
    $ python3 manage.py migrate
    # スーパーユーザー作成
    $ python3 manage.py createsuperuser
    # Django アプリを起動
    $ python3 manage.py runserver 0.0.0.0:8181
    
  3. 動作確認する

    • admin サイトからログアウト

    • GitHub からもログアウト

    • http://localhost:8181/accounts/login/ へアクセス

    • GitHub リンク押下

      /images/django/allauth/01_login.png
      /images/django/allauth/02_sign-in-to-github.png
      /images/django/allauth/03_authorize-fuminote.png
      • 今いま callback URL がエラーになる => メールを設定していないからかもしれない => あとでやってみる

        /images/django/allauth/06_social-login-error.png
    • ログインできた!

      /images/django/allauth/04_home.png
  4. ソーシャル連携解除

できあがるレコード

auth_user

Django サイトのユーザー

account_emailaddress

Django サイトのユーザーと Email

socialaccount_socialtoken

サービスプロバイダから払いだされたトークン

socialaccount_socialaccount

Django サイトのユーザーとサービスプロバイダから払いだされたトークンとを関連付けるソーシャルアカウント

  • サービスプロバイダから連携されたユーザー情報を保持

socialaccount_socialapp

http://localhost:8181/admin/socialaccount/socialapp/ で登録したサービスプロパイダ

  • 今回の場合だと GitHub に登録した OAuth アプリケーションの Client IDClient Secret を保持

socialaccount_socialapp_sites

サービスプロパイダとサイトの紐付け

settings

settings.py
"""
Django settings for fufu project.

Generated by 'django-admin startproject' using Django 2.2.7.

For more information on this file, see
https://docs.djangoproject.com/en/2.2/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.2/ref/settings/
"""

import os
import environ  # https://github.com/joke2k/django-environ

env = environ.Env(
    # set casting, default value
    DEBUG=(bool, False)
)
# reading .env file
environ.Env.read_env()

# False if not in os.environ
DEBUG = env('DEBUG')

# Raises django's ImproperlyConfigured exception if SECRET_KEY not in os.environ
SECRET_KEY = env('SECRET_KEY')

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/

ALLOWED_HOSTS = ['*']

# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # django-allauth ######
    'django.contrib.sites',  # django-allauth では sites フレームワーク必須
    'allauth',
    'allauth.account',
    'allauth.socialaccount',
    'allauth.socialaccount.providers.github',  # GitHub とソーシャル連携
    'bootstrap4',  # https://pypi.org/project/django-bootstrap4/
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'fufu.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')]
        ,
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'fufu.wsgi.application'


# Database
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}


# Password validation
# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/2.2/topics/i18n/

# 日本語にするとテンプレートも勝手に日本語で表示される
LANGUAGE_CODE = 'ja'
# 英語にするとテンプレートも勝手に英語で表示される
# LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'Asia/Tokyo'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.2/howto/static-files/

STATIC_URL = '/static/'

##################
# Authentication #
##################

# メールアドレスとパスワードで認証
AUTHENTICATION_BACKENDS = (
    # デフォルト: これを残しておくと管理画面はユーザー名/パスワードで認証できる
    'django.contrib.auth.backends.ModelBackend',
    'allauth.account.auth_backends.AuthenticationBackend',  # django-allauth を追加
)
# 認証⽅式を 「メールアドレスとパスワード」 に変更
ACCOUNT_AUTHENTICATION_METHOD = 'email'
# ユーザー名は使⽤しない
ACCOUNT_USERNAME_REQUIRED = False

# django-allauth にはこれが必要
SITE_ID = 1

LOGIN_REDIRECT_URL = 'home'
ACCOUNT_LOGOUT_REDIRECT_URL = '/accounts/login/'

# ログアウトリンクログアウトさせたい場合 True
# (デフォルトはログアウト画面経由で POST リクエスト)
ACCOUNT_LOGOUT_ON_GET = True

# ユーザー登録時にメールアドレス確認を行う
ACCOUNT_EMAIL_VARIFICATION = 'mandatory'
# ユーザー登録時にメールアドレス確認を行わない
# ACCOUNT_EMAIL_VARIFICATION = 'none'
# ユーザー登録画面でにEmailを必須項目にする
ACCOUNT_EMAIL_REQUIRED = True

##################
# AWS settings   #
##################
AWS_ACCESS_KEY_ID = env('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = env('AWS_SECRET_ACCESS_KEY')

##################
# Email settings #
##################
# Amazon SES を使う場合
# https://pypi.org/project/django-ses/
EMAIL_BACKEND = 'django_ses.SESBackend'
# us-east-1 以外のAWSリージョンを使用する場合はこれも必要↓
# AWS_SES_REGION_NAME = 'us-west-2'
# AWS_SES_REGION_ENDPOINT = 'email.us-west-2.amazonaws.com'

DEFAULT_FROM_EMAIL = SERVER_EMAIL = 'no-reply <no-reply@32imuf.com>'

メールを設定した

  • callback URL はエラーにならず、 Confirm E-mail Address メール が送られてくるようになった。

    • Confirm E-mail Address メールが送られてくるのは、 settings に ユーザー登録時にメールアドレス確認を行う と設定しているためです

    • メールの設定は Django: メールを送信する を参照のこと

  • 流れ

    1. ログイン画面で GitHub リンク押下する

      /images/django/allauth/11_sign_in.png
    2. GitHub 側のサインイン画面へ遷移する

      /images/django/allauth/12_continue_to_fuminote.png
    3. GitHub でサインインすると、自分のアプリのホーム画面へ遷移する。

    4. 同時に、 GitHub に登録してある Email address に Confirm E-mail Address メールが届く。

      /images/django/allauth/13_confirm_email.png
    5. Confirm E-mail Address メールに記載のリンクを押下すると、 E-mail Address 確認画面へ遷移する。

      /images/django/allauth/14_confirm_email_screen.png
    6. Confirm ボタンを押下するとホーム画面が表示される。

      /images/django/allauth/15_home.png
    7. おまけ: Amazon SES をセットアップした の図 (ちゃんと送られてきたー)

      /images/django/allauth/16_mail-detail-aws-ses.png