django-allauthでログイン機能(ユーザ認証機能)を実装する

# 概要
- Djangoのログイン機能(ユーザ認証)の実装には、標準の`django.contrib.auth`がある。([公式ページ](https://docs.djangoproject.com/en/3.0/topics/auth/))
- `django-allauth`を使うと、簡単に実装できる
    - TwitterアカウントやGitHubアカウントなどでもログインできる。[公式ページ](https://www.intenct.nl/projects/django-allauth/)、[ドキュメント](https://django-allauth.readthedocs.io/en/latest/index.html)を参照。個別に設定が必要なので、今回は割愛。
- 今回は、メルアドとパスワードでの認証にする


# 環境
- Python 3.6.9 (2019-07-02)
- Django 3.0.3 (2020-02-03)
- django-allauth 0.41.0 (2019-12-18)

# 準備
- django-adminの`startproject`で、プロジェクトを作成しておく
- manage.pyの`createsuperuser`で、管理者ユーザを作成しておく
- パスワードリセットのメールを送信するので、メールアカウントを作成しておく(Gmailとか)
    - Gmailを使う場合は「安全性の低いアプリのアクセス」を「有効」にしておく必要がある


# django-allauth のインストール
- `pip install django-allauth`
- 必要に応じて、`pip freeze > requirements.txt`でパッケージリストを更新

# 実装

## settings.py の変更
- INSTALLED_APPS に以下を追加

```
    'django.contrib.sites',
    'allauth',
    'allauth.account',
    'allauth.socialaccount',    # ソーシャル連携認証を使っていない場合でも必要
```

- TEMPLATES の'context_processors'内に以下を追加

```
        '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',
                # `allauth` needs this from django
                'django.template.context_processors.request',
            ],
        },
```



- メルアドとパスワードで認証するために、認証バックエンドを設定
MIDDLEWAREの設定の次あたりに、以下を追加(公式サイトでは丸カッコではなく角カッコなので注意)

```
AUTHENTICATION_BACKENDS = [
    'django.contrib.auth.backends.ModelBackend',
    'allauth.account.auth_backends.AuthenticationBackend',
]
```



- 一番下に以下を追加

```
# sitesフレームワーク用のサイトID
SITE_ID = 1

# ログイン・ログアウト時のリダイレクト先
LOGIN_REDIRECT_URL = 'home'
ACCOUNT_LOGOUT_REDIRECT_URL = '/accounts/login/'

# 認証方式を「メルアドとパスワード」に設定
ACCOUNT_AUTHENTICATION_METHOD = 'email'
# ユーザ名は使用しない
ACCOUNT_USERNAME_REQUIRED = False

# ユーザ登録時に確認メールを送信するか(none=送信しない, mandatory=送信する)
ACCOUNT_EMAIL_VERIFICATION = 'none'
ACCOUNT_EMAIL_REQUIRED = True   # ユーザ登録にメルアド必須にする
```





## urls.py の修正
- 以下を追加

```
from django.urls import include, path   # includeを追加
from django.views.generic import TemplateView   # 追加
```

- urlpatterns に以下を追加

```
    path('', TemplateView.as_view(template_name='home.html'), name='home'),
    path('accounts/', include('allauth.urls')),
    # path('accounts/', include('django.contrib.auth.urls')), # 不要
```

## 基底テンプレートの修正
- templates/base.html 内のbodyブロックの下に、以下を追加

```
      {% block content %}
      {% endblock %}
```


## homeテンプレートの追加
- templates/home.html を作成する

```
{% extends "base.html" %}
{% block title %}Home{% endblock %}
{% load static %}

{% block body %}
this is home.html
{% endblock %}
```


## DBにマイグレーション実行
- `python3 manage.py migrate`

(直前にDB初期化した場合は、`createsuperuser` も実行)


# ブラウザで動作確認
- webサーバ起動
`python3 manage.py runserver 0.0.0.0:8000`

- ログイン画面からログイン
http://localhost:8000/accounts/login/ を開く

    - ここでログイン画面が表示されず、home(http://localhost:8000) に飛ばされる場合は、すでにログイン済みなので、クッキーを消すか、http://localhost:8000/accounts/logout/ を表示して、「Sign Out」ボタンを押してログアウトする)


# ユーザ名を表示する
- テンプレートに以下を追加すると、ログイン中のユーザ名が表示できる

```
{% load account %}

{% user_display user %}
```


# ユーザ認証関連のテンプレートファイルの配置
- templatesというフォルダに各アプリのテンプレートをまとめて配置してあるとして、
- `cp -r /usr/local/lib/python3.6/dist-packages/allauth/templates/account templates/`



# 参考書籍
- 「[現場で使えるDjangoの教科書 実践編](https://www.amazon.co.jp/dp/B07L3DRGBT)」、横瀬昭仁・著


# 参考URL
- [django-allauth ドキュメント](https://django-allauth.readthedocs.io/en/latest/index.html)
- [django-allauth 公式ページ](https://www.intenct.nl/projects/django-allauth/)
- [Django allauthにおけるログイン画面の作成](https://qiita.com/kwashi/items/8421cf45bfaee9e6e238)
- [Djangoのユーザ認証まとめ](https://nwpct1.hatenablog.com/entry/django-oauth-twitter-facebook-github)
    - 記事が2015年と古いが、ログイン済みユーザのみ閲覧できるページ(`login_required`デコレータ)や、Userモデルのカスタマイズなどが書かれている。

- [爆速で作れるDjangoユーザ認証機能【django-allauth】](https://sinyblog.com/django/django-allauth/)
    - テンプレートの書き換えが、「\venv\<仮想環境名>\Lib\site-packages\allauth\templates」を直接書き換えるように書かれているので、デプロイ時に注意。
- [django-allauthでログイン機能を実装する](https://qiita.com/yukidallas/items/12ce3af85a38aaa58332)