2021-01-25: 追記
ソーシャルログインだけでなく、通常のログインもやりたかったので、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を見れば分かる
追記
/templates/account以下ならokではなく、TEMPLATESのDIRSで
TEMPLATES = [
{
....
'DIRS': [
os.path.join(BASE_DIR, 'templates'),
os.path.join(BASE_DIR, 'templates','account'),
],
...
}
]
みたいにパスを追加しておけば、どのフォルダでもok。
使える機能
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
メッセージの変更
例えばログインメッセージは
templates\/account\/messages\/logged_in.txt
にあったりするので、DIRSで通したパスの下にフォルダを作って配置すれば上書きできる・・・はず。
参考:How to clean up Django login message from framework
リンクの貼り方
loginページなどへリンクが貼りたい時のやりかた
<a href="{% url 'account_login' %}">ログイン</a>
<a href="{% url 'account_logout' %}">ログアウト</a>
<a href="{% url 'account_signup' %}">サインアップ</a>
<a href="{% url 'account_change_password' %}">パスワード変更</a>
<a href="{% url 'account_inactive' %}">退会</a>
みたいにする
django-allauth/allauth/account/urls.py
登録時のEmail認証にGmailを使う
django-allauth - Send email verification using Gmail account
ここそのままでいけた。
EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = DEFAULT_FROM_EMAIL = 'gmail account'
EMAIL_HOST_PASSWORD = 'gmail password'
usernameを使わない
setting.pyで
ACCOUNT_USER_MODEL_USERNAME_FIELD = 'username'
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_EMAIL_REQUIRED = True
こんな感じでよさげ。
django allauth empty username causes duplicate key in postgress DB