Django AllAuthで
ログイン後のリダイレクトが効かないとき
LOGIN_REDIRECT_URL は書いた。それでもログイン後は毎回トップに飛ばされる。設定が無視されているのではなく、別の値に上書きされているのが原因です。
django-allauth はバージョン間で設定キーやテンプレートの置き場所が変わります。本番とローカルで版が違うと、テンプレートの上書きが片方だけ黙って無視されることがあるので、まず pip show django-allauth で版を揃えてから読んでください。
Djangoでユーザー認証を実装する際、AllAuthは非常に便利なツールです。しかし、ログイン後のリダイレクトが期待通りに動作しないことがあります。今回は、この問題を解決する方法を詳しく解説します。
問題の背景
AllAuthを使用したログインフォームで、nextパラメータを使ってカスタムリダイレクト先を指定しても、うまく機能しないケースがありました。
解決方法
1. login.htmlの修正
まず、login.htmlテンプレートを以下のように修正します:
<div class=”form-content”>
<h1 class=”mb-4″>ログイン</h1>
<form method=”post” action=”{% url ‘account_login’ %}”>
{% csrf_token %}
{% bootstrap_form form %}
{% if redirect_field_value %}
<input type=”hidden” name=”{{ redirect_field_name }}” value=”{{ redirect_field_value }}” />
{% endif %}
<button class=”btn btn-info btn-block” type=”submit”>ログイン</button>
<!– その他のフォーム要素 –>
</form>
</div>
ここでのポイントは、redirect_field_valueが存在する場合に隠しフィールドとして追加することです。これにより、リダイレクト先の情報がフォーム送信時に含まれるようになります。
2. CustomLoginViewの実装
次に、views.pyにカスタムログインビューを実装します:
from django.utils.http import url_has_allowed_host_and_scheme
from allauth.account.views import LoginView as BaseLoginView
from django.conf import settings
class CustomLoginView(BaseLoginView):
def get_success_url(self):
redirect_to = self.request.POST.get(
self.redirect_field_name,
self.request.GET.get(self.redirect_field_name, ”)
)
url_is_safe = url_has_allowed_host_and_scheme(
url=redirect_to,
allowed_hosts=self.get_success_url_allowed_hosts(),
require_https=self.request.is_secure(),
)
return redirect_to if url_is_safe else settings.LOGIN_REDIRECT_URL
def get_success_url_allowed_hosts(self):
return [self.request.get_host(), *settings.ALLOWED_HOSTS]
このカスタムビューでは:1. POSTとGETの両方からリダイレクト先を取得します。2. url_has_allowed_host_and_scheme関数を使用して、リダイレクト先のURLが安全かどうかをチェックします。3. 安全なURLの場合はそこにリダイレクトし、そうでない場合はsettings.LOGIN_REDIRECT_URLにリダイレクトします。
3. URLの設定
最後に、urls.pyでこのカスタムビューを使用するように設定します:
from .views import CustomLoginView
urlpatterns = [
# … 他のURLパターン …
path(‘accounts/login/’, CustomLoginView.as_view(), name=’account_login’),
# … 他のURLパターン …
]
まとめ
これらの変更により、AllAuthを使用したログインフォームでnextパラメータを正しく処理し、安全なリダイレクトを実現できます。セキュリティと利便性の両方を考慮したこの方法は、多くのDjangoプロジェクトで役立つでしょう。—この記事は、問題の背景、具体的な解決方法、そしてコードの説明を含んでおり、同様の問題に直面している他の開発者にとって有用な情報源となるでしょう。
認証まわりの「効かない」は、たいてい設定が間違っているのではなく、優先順位を読み違えています。