Django通用表单视图登录后重定向至next参数指定页面的问题
解决Django Generic Form View登录后重定向到next参数的问题
你遇到的问题核心是当前代码里的success_url是固定值,没有读取URL中携带的next参数。要实现登录后跳转到next指定的页面,有两种优雅的解决方式,下面是具体实现:
方法一:重写get_success_url(推荐,符合类视图设计)
这种方式把跳转逻辑封装到专门的方法中,更贴合Django类视图的设计理念:
from django.utils.http import is_safe_url from django.conf import settings from django.urls import reverse_lazy from django.views import generic from django.contrib.auth import authenticate, login class LoginView(views.AnonymousRequiredMixin, generic.FormView): form_class = LoginForm # 保留默认跳转地址作为备选 success_url = reverse_lazy('home') template_name = 'accounts/registered/login.html' def get_success_url(self): # 从GET参数中提取next值 next_url = self.request.GET.get('next') # 验证next_url的安全性,防止跳转到外部恶意网站 if next_url and is_safe_url( next_url, allowed_hosts=self.request.get_host(), require_https=settings.IS_HTTPS # 根据你的站点HTTPS配置调整 ): return next_url # 如果没有next参数或参数不安全,使用默认跳转地址 return super().get_success_url() def form_valid(self, form): username = form.cleaned_data['username'] password = form.cleaned_data['password'] user = authenticate(username=username, password=password) if user is not None and user.is_active and user.is_seller: login(self.request, user) return super(LoginView, self).form_valid(form) else: return self.form_invalid(form)
方法二:在form_valid中直接处理重定向
如果你想在登录逻辑里直接处理跳转逻辑,可以修改form_valid方法:
from django.shortcuts import redirect from django.utils.http import is_safe_url from django.conf import settings class LoginView(views.AnonymousRequiredMixin, generic.FormView): form_class = LoginForm success_url = reverse_lazy('home') template_name = 'accounts/registered/login.html' def form_valid(self, form): username = form.cleaned_data['username'] password = form.cleaned_data['password'] user = authenticate(username=username, password=password) if user is not None and user.is_active and user.is_seller: login(self.request, user) # 获取并验证next参数 next_url = self.request.GET.get('next') if next_url and is_safe_url( next_url, allowed_hosts=self.request.get_host(), require_https=settings.IS_HTTPS ): return redirect(next_url) # 无有效next参数时使用默认跳转 return super().form_valid(form) else: return self.form_invalid(form)
重要安全提示
一定要用is_safe_url验证next参数,这能避免攻击者构造恶意链接诱导用户跳转到钓鱼网站。验证时要传入当前请求的主机名,同时根据站点是否启用HTTPS调整require_https参数。
修改完成后,当用户访问http://127.0.0.1:8000/accounts/login/?next=/accounts/dashboard/并登录成功,就会自动跳转到/accounts/dashboard/页面了。
内容的提问来源于stack exchange,提问作者Pankaj Sharma
相关产品推荐
相关产品推荐

