ソーシャルログインだけでなく、通常のログインもやりたかったので、django-allauthを試してみた。

インストール

pipで

pip install django-allauth

ファイルでの設定

settings.pyとurls.pyを設定

# settings.py
INSTALLED_APPS = (
...
    'allauth',
    'allauth.account',
    'allauth.socialaccount',
    'allauth.socialaccount.providers.twitter', #例としてTwitter
)
AUTHENTICATION_BACKENDS = (
...
    'allauth.account.auth_backends.AuthenticationBackend',
)
TEMPLATE_CONTEXT_PROCESSORS = (
...
    "django.core.context_processors.request",
    "django.contrib.auth.context_processors.auth",
    "allauth.account.context_processors.account",
    "allauth.socialaccount.context_processors.socialaccount",
)
SITE_ID = 1
# urls.py
urlpatterns = patterns('',
    ...
    url('^accounts/', include('allauth.urls')),
    url('^accounts/profile/?', include('profile.urls',namespace='profile')), #ログイン後のリダイレクト先
)

adminページでの設定

ソーシャルログインする場合のみ必要。 http://domain/admin/ にアクセスして管理者ログインしてSocial applicationを追加する。 フォーム内では名前を適当に付けて、Twitterの場合Client idにConsumer keyを登録して、Secret keyにConsumer secretを登録すればおk 最後に、利用可能サイトから一番上のサイト(SITE_ID=1と指定してるので)を選択するとおk

http://domain/accounts にアクセスすればログインフォームが出てくる。出来た。

テンプレートを上書きする

プロジェクトディレクトリ/templates/account以下にファイルを設定すればおk 例えばログインのテンプレートなら、login.htmlを設置すればおk

元のファイルはgithubを見れば分かる

使える機能

githubのコード 見れば大体分かる感じ

ユーザー登録時のメール確認後の処理でハマる

ユーザー登録すると通常は登録したメールアドレスにメールが届いて、そこに書いてあるURLにアクセスすると登録完了する手順が表示される。そこらへんの文章とかも上のテンプレート上書きでいけて問題ないんだけど、初期状態では登録が最後まで完了すると、そのままログインしてログイン時のリダイレクト先に移動してしまう。完了画面を表示したい場合はこれではまずい。

ので、ここらへんのCustom Redirectsの項目を参考にしてアダプタを作ってみた

# settings.py
ACCOUNT_ADAPTER = 'project.users.adapter.MyAccountAdapter'
# project/users/adapter.py
from django.conf import settings
from allauth.account.adapter import DefaultAccountAdapter

class MyAccountAdapter(DefaultAccountAdapter):
    def get_email_confirmation_redirect_url(self,request):
        path = "/account/complete"
        return path

でもこれだけでは上手くいかなかった。普通にログイン時のリダイレクト先に移動してしまった。どうもACCOUNT_LOGIN_ON_EMAIL_CONFIRMATIONをFalseにしないとダメみたい

# settings.py
ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION = False

これでやっと/account/completeにリダイレクトしてくれた。ログインした状態ではダメみたいなので、ログインは再度やってもらわないといけない。うーん今のとこ仕方ないか・・・。

django-allauthのサインアップフォームをカスタマイズしたい

あるフィールドにhelp_textを付ける

参考:Overwrite django-allauth form field - Stack Overflow

__init__を上書きして、フィールドに属性を追加する コードはこんな感じ。例としてユーザー名入力フォームにヘルプテキストとして「required」という文字を追加する

# appname/forms.py
from django import forms

class SignupForm(forms.Form):
  def __init__(self, *args, **kwargs):
    super(SignupForm, self).__init__(*args, **kwargs)
    self.fields['username'].help_text = "required"
# settings.py
ACCOUNT_SIGNUP_FORM_CLASS = "appname.forms.SignupForm"

こんな感じ

フィールドのバリデーションを追加

参考:python - How to clean username with Django allauth adapter? - Stack Overflow

Account Adapterを設定してあげて、そこでclean_xxxを作ると上手くいくみたい

```py
# project/users/adapter.py
class MyAccountAdapter(DefaultAccountAdapter):
    ...
    def clean_username(self, username):
        " 適当に処理を入れる
        " エラーの場合はraise Exception
        return username