You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django REST-Auth重置密码链接含%20%0A,令牌无法正常使用求助

Django REST-Auth密码重置链接含%20/%0A编码的问题解决

我之前帮几个开发者解决过这个一模一样的问题,咱们一步步来拆解问题成因和修复方案:

问题成因

这个编码问题的核心是密码重置链接里混入了空格(%20)和换行符(%0A),这些空白字符在生成URL时被自动编码了。具体来源通常有两个:

  • django-rest-auth 0.9.5版本的默认邮件模板里,重置链接被换行/缩进处理了,导致生成的URL包含多余的空白;
  • 你自定义的邮件发送逻辑(比如重写序列化器或视图时),不小心给链接添加了换行或空格。

看你提供的链接:http://127.0.0.1:8000/password-reset/confirm/MTY0MjM0MGMtNGEyMi00ZmY5LWE3YzgtNDdiOGM2M2ViYzIy/%20%0A%20%20%20%20%20%20%20%205d9-2e76cc7a3bc99cf6f1ed/,明显是令牌部分前面有换行和空格,这大概率是模板里的格式问题。

修复方案

1. 修复默认邮件模板(最直接有效)

django-rest-auth的默认密码重置模板路径是rest_auth/password_reset_email.html,你需要把这个模板拷贝到自己项目的templates目录下,然后修改链接部分,确保它是连续的一行,没有多余的空格或换行。

修改前的模板片段(可能存在的问题):

Please go to the following page and choose a new password:
{{ protocol }}://{{ domain }}/{{ url|safe }}

这里的链接被单独换行,加上模板的缩进,会导致生成的URL带空白。

修改后的模板片段:

Please go to the following page and choose a new password: {{ protocol }}://{{ domain }}/{{ url|safe }}

或者把链接放在单独一行,但要保证链接本身没有被拆分、前后无多余空格:

Please go to the following page and choose a new password:
{{ protocol }}://{{ domain }}/{{ url|safe }}

2. 重写PasswordResetSerializer确保链接无空白

如果你已经自定义了序列化器,检查get_email_options方法,确保传递给模板的参数没有引入空白。示例代码:

from rest_auth.serializers import PasswordResetSerializer

class CustomPasswordResetSerializer(PasswordResetSerializer):
    def get_email_options(self):
        return {
            'email_template_name': 'rest_auth/password_reset_email.html',
            # 确保所有参数(比如domain、protocol)没有多余空白
            'extra_email_context': {
                'domain': self.context['request'].get_host().strip(),
                'protocol': 'https' if self.context['request'].is_secure() else 'http',
            }
        }

3. 手动清理链接中的空白字符(兜底方案)

如果上面的方法都没解决,可以在生成链接后手动去除空白。重写PasswordResetView的send_reset_email方法:

from rest_auth.views import PasswordResetView
from django.core.mail import send_mail

class CustomPasswordResetView(PasswordResetView):
    def send_reset_email(self, user):
        # 调用父类方法获取邮件内容的上下文
        context = self.get_email_context(user)
        # 清理链接中的空白
        context['url'] = context['url'].strip()
        # 重新构建邮件内容并发送
        subject_template_name = 'rest_auth/password_reset_subject.txt'
        email_template_name = 'rest_auth/password_reset_email.html'
        
        subject = self.render_to_string(subject_template_name, context)
        subject = ''.join(subject.splitlines())  # 去除主题中的换行
        email = self.render_to_string(email_template_name, context)
        
        send_mail(subject, email, None, [user.email])

总结

这个问题本质上是空白字符的编码问题,90%的情况都是邮件模板的格式导致的。先检查模板,把链接部分的多余空白去掉,基本就能解决。如果是自定义逻辑引入的空白,针对性清理即可。

内容的提问来源于stack exchange,提问作者TJA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 10:34:09