Python
Django

django-allauthでログイン機能を実装する

More than 1 year has passed since last update.

前回の続きです。

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します。


requirements.txt

django==1.11

django-allauth==0.31.0 # 追加
django-extensions==1.7.8
mysqlclient==1.3.10



terminal

pip install -r requirements.txt -t libs



メールアドレスで登録/ログイン

INSTALLED_APPSにdjango adminとallauthを追加します。


django-sample/settings.py

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クラスを作成します。


django-sample/views.py

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ライブラリ内にあるものをコピーしてきました。


templates/signin/index.html

{% block content %}

<form method="post" action="{% url 'account_login' %}">
{% csrf_token %}
{{form.as_p}}
<button type="submit">Sign In</button>
</form>
{% endblock %}



templates/signup/index.html

{% 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 %}

ルーティングを追加します。


django-sample/urls.py

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とルーティングを追加します。


django-sample/views.py

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()



django-sample/urls.py

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には以下を値を設定してください。


callback_url

http://localhost:8000/auth/twitter/login/callback/


Django側でallauth周りの設定を追加していきます。


django-sample/settings.py

INSTALLED_APPS = [

# {...}
'allauth.socialaccount',
'allauth.socialaccount.providers.twitter'
]

Django adminにアクセスするためのルーティングを追加します。


django-sample/urls.py

# {...}

from django.contrib import admin
admin.autodiscover()

urlpatterns = [
# {...}
url(r'^admin/', include(admin.site.urls))
]


管理画面にログインするためのアカウントを作成します。


terminal

$ 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ログイン(登録)ができます。

画面上にリンクを出したい場合は以下のようにします。


templates/home/index.html

<a href="/auth/twitter/login/">Twitterでログイン</a>

<!-- または -->
<a href="{% url 'twitter_login' %}">Twitterでログイン</a>

rails routesみたいにルーティング周りを確認したい場合は以下のコマンドを使用します。

(django-extensions)


terminal

$ 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


ログインしているかどうかで出し分けるには以下のようにします。


templates/home/index.html

{% if user.is_authenticated %}

<p>こんにちは {{ user.username }}さん</p>
{% else %}
<p>ログインしてください</p>
{% endif %}


おまけ

ログインに使用するモデルを自由にカスタマイズすることができます。


terminal

$ cd ./django-sample/django-sample

$ python ../manage.py startapp accounts


django-sample/settings.py

INSTALLED_APPS = [

# {...}
'django-sample.accounts'
]


django-sample/accounts/models.py

from django.db import models

from django.contrib.auth.models import AbstractUser, UserManager

class User(AbstractUser):
objects = UserManager()

class Meta(object):
app_label = 'accounts'



django-sample/settings.py

AUTH_USER_MODEL = 'accounts.User'


データベースのマイグレーションをします。

migrateでコケる場合は一度データベースを消してやり直すといいかもしれません。


terminal

$ python manage.py makemigrations

$ python manage.py migrate


最後に

一応Githubにソースを載せています(前回のものを更新してます)

https://github.com/yukidallas/django-sample