如何在Django与Wagtail中实现表单密码认证及二维码免密访问
解决方案:区分扫码与正常访问的密码验证逻辑
要实现扫码直接访问、手动输入URL需验证密码的需求,核心思路是给扫码的URL添加特殊验证参数,在页面访问限制逻辑中识别该参数并跳过验证,具体步骤如下:
1. 生成带验证参数的二维码URL
将你的ProfilePage页面URL拼接上自定义的验证参数,例如:https://your-domain.com/profile-page/?skip_password=your_unique_secret
把这个拼接后的URL生成二维码,用户扫码访问时就会自动携带该参数。
2. 修改页面模型的访问限制逻辑
重写ProfilePage的check_view_restriction方法,识别请求中的验证参数,合法则跳过密码验证:
from wagtail.core.models import Page, PageViewRestriction from django.utils.translation import gettext_lazy as _ class ProfilePage(Page): template = 'profile/profile_page.html' def get_context(self, request, *args, **kwargs): context = super().get_context(request, *args, **kwargs) return context def check_view_restriction(self, request, serve_args, serve_kwargs): # 读取URL中的跳过验证参数 skip_param = request.GET.get('skip_password') # 验证参数是否匹配预设的密钥(请替换成你自己的随机密钥) if skip_param == 'your_unique_secret_key_123': # 参数合法,跳过密码验证 return None # 参数不合法或不存在,执行默认的密码验证逻辑 restriction = PageViewRestriction.objects.filter(page=self).first() if restriction: return restriction.check(request) return None def save(self, *args, **kwargs): # 避免重复创建页面访问限制,先删除已有限制再创建 self_page = ProfilePage.objects.all().first() if self_page: PageViewRestriction.objects.filter(page=self_page).delete() PageViewRestriction.objects.create(page=self_page, restriction_type='password') return super().save(*args, **kwargs)
3. 关键说明
- 安全保障:不要使用
1/true这类简单值作为验证参数,建议使用随机生成的字符串作为密钥,防止他人构造URL绕过验证。 - 默认逻辑兼容:当用户手动输入URL(无验证参数)时,会自动触发原有的密码验证流程,无需修改密码模板。
- 重复限制修复:原save方法每次保存都会创建新的PageViewRestriction,修改后先删除已有限制再创建,避免多条限制冲突。
内容的提问来源于stack exchange,提问作者Squall32
相关产品推荐
相关产品推荐

