前回の続きです。
http://qiita.com/yukidallas/items/9cd0ca5cda7f459533c3
django-allauth
Djangoアプリケーション上でソーシャルログインを簡単に実装できるライブラリです。
https://github.com/pennersr/django-allauth
現在以下のソーシャルログインに対応しているようです。
- Amazon (OAuth2)
- AngelList (OAuth2)
- Bitly (OAuth2)
- Dropbox (OAuth)
- Facebook (both OAuth2 and JS SDK)
- Feedly (OAuth2)
- Github (OAuth2)
- Google (OAuth2)
- Instagram (OAuth2)
- LinkedIn (OAuth, OAuth2)
- OpenId
- Paypal (OAuth2)
- Persona
- SoundCloud (OAuth2)
- Stack Exchange (OAuth2)
- Twitch (OAuth2)
- Twitter (OAuth)
- Vimeo (OAuth)
- VK (OAuth2)
Weibo (OAuth2)
インストール
requirements.txtにdjango-allauthを追加してpip installします。
django==1.11
django-allauth==0.31.0 # 追加
django-extensions==1.7.8
mysqlclient==1.3.10
pip install -r requirements.txt -t libs
メールアドレスで登録/ログイン
INSTALLED_APPSにdjango adminとallauthを追加します。
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.messages',
'django.contrib.sessions',
'django.contrib.staticfiles',
'django.contrib.sites',
'django_extensions',
'allauth',
'allauth.account'
]
AUTHENTICATION_BACKENDS = [
'allauth.account.auth_backends.AuthenticationBackend'
]
登録/ログイン周りのViewクラスを作成します。
from allauth.account import views
class SigninView(views.LoginView):
template_name = 'signin/index.html'
def dispatch(self, request, *args, **kwargs):
response = super(SigninView, self).dispatch(request, *args, **kwargs)
return response
def form_valid(self, form):
return super(SigninView, self).form_valid(form)
signin_view = SigninView.as_view()
class SignupView(views.SignupView):
template_name = 'signup/index.html'
def get_context_data(self, **kwargs):
context = super(SignupView, self).get_context_data(**kwargs)
return context
signup_view = SignupView.as_view()
対応するテンプレートを作成します。
allauthにもデフォルトテンプレートがありますが、カスタマイズする場合がほとんどなので別途用意しました。
コードはallauthライブラリ内にあるものをコピーしてきました。
{% block content %}
<form method="post" action="{% url 'account_login' %}">
{% csrf_token %}
{{form.as_p}}
<button type="submit">Sign In</button>
</form>
{% endblock %}
{% block content %}
<form method="post" action="{% url 'account_signup' %}">
{% csrf_token %}
{{ form.as_p }}
{% if redirect_field_value %}
<input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
{% endif %}
<button type="submit">Signup</button>
</form>
{% endblock %}
ルーティングを追加します。
urlpatterns = [
url(r'^$', views.home_view),
url(r'^auth/', include('allauth.urls')),
url(r'^signin/?$', views.signin_view),
url(r'^signup/?$', views.signup_view),
]
http://localhost:8000/signup にアクセスしユーザー登録、
http://localhost:8000/signin でログインができるようになります。
このままではサインアウトができないのでViewとルーティングを追加します。
from django.shortcuts import redirect
class SignoutView(views.LogoutView):
def get(self, *args, **kwargs):
return self.post(*args, **kwargs)
def post(self, *args, **kwargs):
if self.request.user.is_authenticated():
self.logout()
return redirect('/')
signout_view = SignoutView.as_view()
urlpatterns = [
# {...}
url(r'^signout/?$', views.signout_view)
]
http://localhost:8000/signout でサインアウトできるようになります。
TwitterアカウントでのSNSログイン
今回はTwitterでのソーシャルログインを実装します。事前にTwitter Developersでアプリを作成しておいて下さい。 電話番号を登録していないとできないみたいです。
https://apps.twitter.com
Create New App → Application Detailsに必要な情報を入力します。
Callback URLには以下を値を設定してください。
http://localhost:8000/auth/twitter/login/callback/
Django側でallauth周りの設定を追加していきます。
INSTALLED_APPS = [
# {...}
'allauth.socialaccount',
'allauth.socialaccount.providers.twitter'
]
Django adminにアクセスするためのルーティングを追加します。
# {...}
from django.contrib import admin
admin.autodiscover()
urlpatterns = [
# {...}
url(r'^admin/', include(admin.site.urls))
]
管理画面にログインするためのアカウントを作成します。
$ python manage.py createsuperuser
http://localhost:8000/adminにアクセスしログインします。
SOCIAL ACCOUNTS > social applications にアクセスし各種設定をします。
- Providor → Twitter
- Name → Twitter
- Client id → {Your Consumer Key (API Key)}
- Secret key → {Your Consumer Secret (API Secret)}
- Sites → Chosen sitesにexample.comを追加
保存後、一度管理画面からログアウトし、http://localhost:8000/auth/twitter/login/にアクセスするとTwitter連携画面に飛ばされてSNSログイン(登録)ができます。
画面上にリンクを出したい場合は以下のようにします。
<a href="/auth/twitter/login/">Twitterでログイン</a>
<!-- または -->
<a href="{% url 'twitter_login' %}">Twitterでログイン</a>
rails routesみたいにルーティング周りを確認したい場合は以下のコマンドを使用します。
(django-extensions)
$ python manage.py show_urls
# 省略
/auth/twitter/login/ allauth.socialaccount.providers.oauth.views.view twitter_login
/auth/twitter/login/callback/ allauth.socialaccount.providers.oauth.views.view twitter_callback
ログインしているかどうかで出し分けるには以下のようにします。
{% if user.is_authenticated %}
<p>こんにちは {{ user.username }}さん</p>
{% else %}
<p>ログインしてください</p>
{% endif %}
おまけ
ログインに使用するモデルを自由にカスタマイズすることができます。
$ cd ./django-sample/django-sample
$ python ../manage.py startapp accounts
INSTALLED_APPS = [
# {...}
'django-sample.accounts'
]
from django.db import models
from django.contrib.auth.models import AbstractUser, UserManager
class User(AbstractUser):
objects = UserManager()
class Meta(object):
app_label = 'accounts'
AUTH_USER_MODEL = 'accounts.User'
データベースのマイグレーションをします。
migrateでコケる場合は一度データベースを消してやり直すといいかもしれません。
$ python manage.py makemigrations
$ python manage.py migrate
最後に
一応Githubにソースを載せています(前回のものを更新してます)
https://github.com/yukidallas/django-sample