Django 2、python 3.4 无法解码 urlsafe_base64_decode(uidb64)
Posted
技术标签:
【中文标题】Django 2、python 3.4 无法解码 urlsafe_base64_decode(uidb64)【英文标题】:Django 2, python 3.4 cannot decode urlsafe_base64_decode(uidb64) 【发布时间】:2018-05-28 14:16:11 【问题描述】:我正在尝试通过电子邮件激活用户, 电子邮件有效,编码有效,我使用了 django1.11 中的一种方法,该方法成功运行。
在 Django 1.11 中,以下成功解码为 28,其中 uidb64 = b'Mjg'
force_text(urlsafe_base64_decode(uidb64))
在 django 2 (2, 0, 0, 'final', 0) 上面的代码解码不起作用并导致错误
django.utils.encoding.DjangoUnicodeDecodeError: 'utf-8' codec can't decode byte 0xc8 in position 1: invalid continuation byte. You passed in b'l\xc8\xe0' (<class 'bytes'>)
我也发布我的观点以防万一
from django.utils.encoding import force_bytes, force_text
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
def signup(request):
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
user.is_active = False
user.save()
# auth_login(request, user)
message = render_to_string('user_activate_email.html',
'user': user,
'domain': Site.objects.get_current().domain,
'uidb64': urlsafe_base64_encode(force_bytes(user.pk)),
'token': account_activation_token.make_token(user),
)
mail_subject = 'Activate your blog account.'
to_email = form.cleaned_data.get('email')
email = EmailMessage(mail_subject, message, to=[to_email])
email.send()
messages.info(
request, 'Activation link has been sent to your email!')
# return redirect('home')
return render(request, 'index.html')
else:
form = SignUpForm()
return render(request, 'user_action.html', 'form': form)
def activate(request, uidb64, token):
try:
import pdb;
pdb.set_trace()
uid = urlsafe_base64_decode(uidb64).decode()
user = User.objects.get(pk=uid)
except(TypeError, ValueError, OverflowError):
user = None
if user is not None and account_activation_token.check_token(user, token):
user.refresh_from_db()
user.is_active = True
user.save()
auth_login(request, user)
messages.info(request, 'Your account has been activated successfully!')
return redirect('events:home')
else:
messages.info(
request, 'Activation link is invalid or has been activated')
return redirect('events:home')
PS:这只是我使用 CBV 之前的一个试验。
编辑:包括回溯
System check identified no issues (0 silenced).
December 15, 2017 - 05:51:01
Django version 2.0, using settings 'event_management.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
> /home/vipinmohan/django2-0/event/event_management/users/views.py(88)activate()
-> uid = urlsafe_base64_decode(uidb64).decode()
(Pdb) n
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xcc in position 1: invalid continuation byte
> /home/vipinmohan/django2-0/event/event_management/users/views.py(88)activate()
-> uid = urlsafe_base64_decode(uidb64).decode()
(Pdb) n
> /home/vipinmohan/django2-0/event/event_management/users/views.py(90)activate()
-> except(TypeError, ValueError, OverflowError):
(Pdb) n
> /home/vipinmohan/django2-0/event/event_management/users/views.py(91)activate()
-> user = None
(Pdb)
【问题讨论】:
请显示完整的回溯。 您能具体说明您要做什么吗?问题不清楚,它说明了一个一般性问题,得到您要解决的问题,请添加完整的回溯,这可能有助于指导您 我已包含回溯。我正在尝试通过激活电子邮件激活用户。当我点击链接时,它不起作用。使用 pdb.set_trace() 会抛出 unicode decode 错误。 【参考方案1】:好的。经过一小时的搜索(仍然是 python django 的初学者),在发行说明中指出了一个相关的变化,其定义对于新手来说并不难。 https://docs.djangoproject.com/en/2.0/releases/2.0/#removed-support-for-bytestrings-in-some-places
为了支持原生 Python 2 字符串,较旧的 Django 版本必须同时接受字节字符串和 unicode 字符串。现在 Python 2 支持被删除了,字节串应该只出现在输入/输出边界附近(例如处理二进制字段或 HTTP 流)。您可能需要更新代码以将字节串的使用限制在最低限度,因为 Django 不再接受某些代码路径中的字节串。
例如,reverse() 现在使用 str() 而不是 force_text() 来 强制它收到的 args 和 kwargs,在它们被放置之前 网址。对于字节串,这会创建一个带有不想要的 b 的字符串 前缀以及附加引号(str(b'foo') is "b'foo'")。到 适应,在将字节串传递给 reverse() 之前调用 decode()。
完全无法理解它的含义,我不得不更深入地研究实际的 django 核心代码。
所以从 django 1.11 到 2.0 的编码变化如下
'uid': urlsafe_base64_encode(force_bytes(user.pk)),
到
'uid': urlsafe_base64_encode(force_bytes(user.pk)).decode(),
并从中解码
uid = force_text(urlsafe_base64_decode(uidb64))
到
uid = urlsafe_base64_decode(uidb64).decode()
就是这样。希望这对某人有所帮助。
******************编辑******************
从 Django 2.2 开始
django.utils.http.urlsafe_base64_encode()
现在返回一个字符串而不是字节串。
并且django.utils.http.urlsafe_base64_decode()
可能不再被传递一个字节串。
感谢 Hillmark 指出
【讨论】:
你是一个救生员。由于这个问题,我一直在努力重置密码几个小时。谢谢 在 2.2 中更改,现在返回字符串而不是字节字符串 docs.djangoproject.com/en/2.2/releases/2.2/#miscellaneous 向你致敬。救生员以上是关于Django 2、python 3.4 无法解码 urlsafe_base64_decode(uidb64)的主要内容,如果未能解决你的问题,请参考以下文章
使用 apache2 在 mod_wsgi 上运行 django python 3.4
Django 1.8.2(使用 Python 3.4):如何将带有选项的 CharField 存储在带有 ENUM 列的 MySQL 表中?