【Django】Djangoで開発環境の構築から、django-allauthを使いfacebookでユーザー認証を行うところまでのTips②

#Django-Facebookを使ってFacebook認証を実装
Djangoが用意しているSNSアカウント認証のパッケージはいくつもありますが(https://djangopackages.org/grids/g/facebook-authentication/ )、
一般的に`Django-Allauth`が広く使われています。

```console
$pip install django-allauth

....
Installing collected packages: defusedxml, python3-openid, oauthlib, urllib3, certifi, chardet, idna, requests, requests-oauthlib, django-allauth
  Running setup.py install for django-allauth ... done
Successfully installed certifi-2018.11.29 chardet-3.0.4 defusedxml-0.5.0 django-allauth-0.38.0 idna-2.8 oauthlib-3.0.1 python3-openid-3.1.0 requests-2.21.0 requests-oauthlib-1.2.0 urllib3-1.24.1
```
`config/settings.py` に下の最後の4行を追加します

```config/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.sites',
    'allauth',
    'allauth.account',
    'allauth.socialaccount',
    'allauth.socialaccount.providers.facebook',
]
```

django-allauthはsitesフレームワークの利用が必要になります。
そこでDjangoサイトを識別する為に、以下の設定を付け加えます。

```config/settings.py
SITE_ID = 1
```

```config/urls.py
urlpatterns = [
    path('admin/', admin.site.urls),
    path('', TemplateView.as_view(template_name='home.html'), name='home'),
    path('accounts/', include('allauth.urls')),
] #<=変更する
```

##Facebookディベロッパーに登録
まずはこちらのリンクから、Facebookディベロッパー登録します。
https://developers.facebook.com/

アプリIDとSecret keyを取得できます。これは後ほど使います。
もし登録はしたことがあるけど自分のアプリIDとSecret keyがわからないという方は、ログイン後トップ画面の
左側のツールバーから[設定]=>[ベーシック]から調べることが可能です。

<img width="1227" alt="スクリーンショット 2019-02-09 22.06.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/265778/cfa54f31-37e5-4c6d-1715-ed5998242b8a.png">

続いてmigrate、runserverします。

```console
$python manage.py migrate
$python manage.py createsuperuser
#管理者のユーザー名、メールアドレス、Passwordを求められる

$python manage.py runserver
```

http://localhost:8000/admin/ に先ほどcreatesuperuserして作成した管理者アカウントでログイン。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/265778/0ea2c61e-a0cf-5aa3-1c2c-cc92ba834a75.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/265778/ca58ede7-5711-668b-8907-4384ca3e67a9.png)

そしてログイン後、「サイト」にアクセスすると,
example.com というサイトができていることがわかります。

管理画面トップに戻り、
[外部アカウント]=>[Social applications]=>[social applicationを追加]を選択していくと、入力画面が現れます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/265778/28d55806-f402-e2e5-72f1-3c1bc583bee9.png)

プロバイダーを選択、名前（Facebookなど）、Client ID、Secret keyを入力し（Client IdとSecret keyはFacebookディベロッパーから取得）、保存します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/265778/d42be05b-ac0e-33a2-fb0b-9ab84e803ba2.png)

##早速ログインを試してみる

管理サイトからログアウトし、http://localhost:8000/accounts/login/ にアクセス。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/265778/03fee9bf-6844-7efa-c1ba-e821dab75fa3.png)

ここはもちろんFacebookリンクにアクセスしましょう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/265778/05c632b6-2634-ec4d-b31c-e38a8e800af2.png)

Facebook認証画面の登場です。
良い感じですね。
自分のFacebookアカウントでログインしてみましょう。

<img width="745" alt="スクリーンショット 2019-02-09 22.32.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/265778/895f9234-d35c-9709-818c-cfc5c6bae448.png">

自身のFacebookの名前が入り、ログインされていることができましたか？
facebookユーザー認証までは以上の流れになります。

#その先
実際はログアウト、パスワードリセット、アカウント削除、ユーザーモデルのアレンジや認証方法のアレンジ（メール認証など）、リダイレクト先やサイトのUIなどやることは山積みですが、これでDjangoでのfacebook認証というとっつきづらそうな課題に風穴を開けたことに間違いはありません。
ちなみに今回はfacebook認証を行いましたが、`django-allauth` を使えば様々なソーシャルアカウントでの認証ができます。例えば...

```python
# ... include the providers you want to enable:
    'allauth.socialaccount.providers.agave',
    'allauth.socialaccount.providers.amazon',
    'allauth.socialaccount.providers.angellist',
    'allauth.socialaccount.providers.asana',
    'allauth.socialaccount.providers.auth0',
    'allauth.socialaccount.providers.authentiq',
    'allauth.socialaccount.providers.baidu',
    'allauth.socialaccount.providers.basecamp',
    'allauth.socialaccount.providers.bitbucket',
    'allauth.socialaccount.providers.bitbucket_oauth2',
    'allauth.socialaccount.providers.bitly',
    'allauth.socialaccount.providers.cern',
    'allauth.socialaccount.providers.coinbase',
    'allauth.socialaccount.providers.dataporten',
    'allauth.socialaccount.providers.daum',
    'allauth.socialaccount.providers.digitalocean',
    'allauth.socialaccount.providers.discord',
    'allauth.socialaccount.providers.disqus',
    'allauth.socialaccount.providers.douban',
    'allauth.socialaccount.providers.draugiem',
    'allauth.socialaccount.providers.dropbox',
    'allauth.socialaccount.providers.dwolla',
    'allauth.socialaccount.providers.edmodo',
    'allauth.socialaccount.providers.eveonline',
    'allauth.socialaccount.providers.evernote',
    'allauth.socialaccount.providers.facebook',
    'allauth.socialaccount.providers.feedly',
    'allauth.socialaccount.providers.fivehundredpx',
    'allauth.socialaccount.providers.flickr',
    'allauth.socialaccount.providers.foursquare',
    'allauth.socialaccount.providers.fxa',
    'allauth.socialaccount.providers.github',
    'allauth.socialaccount.providers.gitlab',
    'allauth.socialaccount.providers.google',
    'allauth.socialaccount.providers.hubic',
    'allauth.socialaccount.providers.instagram',
    'allauth.socialaccount.providers.jupyterhub',
    'allauth.socialaccount.providers.kakao',
    'allauth.socialaccount.providers.line',
    'allauth.socialaccount.providers.linkedin',
    'allauth.socialaccount.providers.linkedin_oauth2',
    'allauth.socialaccount.providers.mailru',
    'allauth.socialaccount.providers.mailchimp',
    'allauth.socialaccount.providers.meetup',
    'allauth.socialaccount.providers.naver',
    'allauth.socialaccount.providers.odnoklassniki',
    'allauth.socialaccount.providers.openid',
    'allauth.socialaccount.providers.orcid',
    'allauth.socialaccount.providers.paypal',
    'allauth.socialaccount.providers.persona',
    'allauth.socialaccount.providers.pinterest',
    'allauth.socialaccount.providers.reddit',
    'allauth.socialaccount.providers.robinhood',
    'allauth.socialaccount.providers.shopify',
    'allauth.socialaccount.providers.slack',
    'allauth.socialaccount.providers.soundcloud',
    'allauth.socialaccount.providers.spotify',
    'allauth.socialaccount.providers.stackexchange',
    'allauth.socialaccount.providers.steam',
    'allauth.socialaccount.providers.stripe',
    'allauth.socialaccount.providers.trello',
    'allauth.socialaccount.providers.tumblr',
    'allauth.socialaccount.providers.twentythreeandme',
    'allauth.socialaccount.providers.twitch',
    'allauth.socialaccount.providers.twitter',
    'allauth.socialaccount.providers.untappd',
    'allauth.socialaccount.providers.vimeo',
    'allauth.socialaccount.providers.vimeo_oauth2',
    'allauth.socialaccount.providers.vk',
    'allauth.socialaccount.providers.weibo',
    'allauth.socialaccount.providers.weixin',
    'allauth.socialaccount.providers.windowslive',
    'allauth.socialaccount.providers.xing',
    ...
)
```

https://django-allauth.readthedocs.io/en/latest/installation.html
(ドキュメントより)

個人的にFBはあまり信頼していないので、一つのパッケージにこうした多くの他の手段が用意されているのは非常にありがたいなと思います。

##ただし難点も...

https://djangopackages.org/grids/g/facebook-authentication/

![image.png](https://qiita-image-store.s3.amazonaws.com/0/265778/39fed7be-3893-aa0d-d3e5-0ff1960e4222.png)

これをみると`django-allauth`はdevelopment statusがBetaのようです。
本番環境で使うには心許ないか。
しかしUpdatedの頻度やStars、Repo Forksの数などをみると、他に比べると`django-allauth`は圧倒的人気を誇っているようですね。

開発にかけられる工数もそれぞれだと思いますので、用途に合わせて使えるよう色々と今後勉強してみたいと思います！