Django 2,Python 3.4无法解码urlsafe_base64_decode(uidb64) [英] Django 2, python 3.4 cannot decode urlsafe_base64_decode(uidb64)

查看:113
本文介绍了Django 2,Python 3.4无法解码urlsafe_base64_decode(uidb64)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图通过电子邮件激活用户,
电子邮件有效,编码有效,我使用了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'编解码器无法解码字节0xc8在位置1:无效的连续字节。您传入了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)),
'令牌':account_activation_token.make_token(user),
})
mail_subject ='激活您的博客unt。'
to_email = form.cleaned_data.get('email')
email = EmailMessage(mail_subject,message,to = [to_email])
email.send()
messages.info(
请求,激活链接已发送到您的电子邮件!)
#返回重定向('home')
返回渲染(request,'index.html')
else:
form = SignUpForm()
return render(request,'user_action.html',{'form':form})


def activate(request,uidb64,令牌):
试试:
import pdb;
pdb.set_trace()
uid = urlsafe_base64_decode(uidb64).decode()
user = User.objects.get(pk = uid)
除了(TypeError,ValueError,OverflowError ):
用户=无
如果user不为None并且account_activation_token.check_token(用户,令牌):

user.refresh_from_db()
user.is_active = True

user.save()
auth_login(请求,用户)
messages.info(请求,'您的帐户已成功激活!')
return redirect( 'events:home')
else:
messages.info(
请求,'激活链接无效或已被激活')
return redirect('events:home')

PS:这只是我使用CBV之前的一项试用。



编辑:包括回溯

 系统检查未发现问题(静默0)。 
2017年12月15日-05:51:01
Django 2.0版,使用设置为'event_management.settings'
在http://127.0.0.1:8000/ $ b $处启动开发服务器b使用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编解码器无法解码位置1的字节0xcc:无效的继续字节
> /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()
->除了(TypeError,ValueError,OverflowError):
(Pdb)n
> /home/vipinmohan/django2-0/event/event_management/users/views.py(91)activate()
->用户=无
(Pdb)


解决方案

好。经过一个小时的搜索(仍然是python django的初学者),发行说明中指出了一个相关的更改,其定义对于新手来说并不困难。
https: //docs.djangoproject.com/zh-CN/2.0/releases/2.0/#re​​moved-support-for-bytestrings-in-some-places


要支持本机Python 2字符串,较早的Django版本必须接受字节字符串和unicode字符串。现在已经放弃了对Python 2的支持,字节串仅应在输入/输出边界(例如,二进制字段或HTTP流的处理)周围遇到。您可能必须更新代码以将字节串使用限制到最小,因为Django不再在某些代码路径中接受字节串​​。



例如,reverse()现在使用str ()代替force_text()强制
强制接收到的args和kwargs,然后再将其放入
中。对于字节串,这将创建一个带有不想要的b
前缀以及其他引号的字符串(str(b'foo')为 b'foo')。为了适应
,请在将字节串传递给reverse()之前,先对它的字节串调用define()。


完全无法使用



因此,从django 1.11到2.0,编码更改如下:

 'uid':urlsafe_base64_encode(force_bytes(user.pk)),

 'uid':urlsafe_base64_encode(force_bytes(user.pk))。decode( ),

并从



<$ p $解码p> uid = force_text(urlsafe_base64_decode(uidb64))

  uid = urlsafe_base64_decode(uidb64).decode()

就是这样。希望这对某人有帮助。



************* EDIT **************** **



自Django 2.2起



django .utils.http.urlsafe_base64_encode()现在返回一个字符串,而不是字节字符串。



django.utils。 http.urlsafe_base64_decode()可能不再传递字节串。



感谢Hillmark指出


i am trying to activate a user by email, email works, encoding works, i used an approach from django1.11 which was working successfully.

In Django 1.11 the following decodes successfully to 28, where uidb64 = b'Mjg'

force_text(urlsafe_base64_decode(uidb64))

In django 2 (2, 0, 0, 'final', 0) the above code decode does not work and results in an error

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'>)

I am also posting my views just in case

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: This is just a trial before i work with CBV.

edit: including traceback

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) 

解决方案

Ok. after hour long search (still beginner at python django), a relevant change was pointed in release notes whose definitions were little difficult for a newcomer. https://docs.djangoproject.com/en/2.0/releases/2.0/#removed-support-for-bytestrings-in-some-places

To support native Python 2 strings, older Django versions had to accept both bytestrings and unicode strings. Now that Python 2 support is dropped, bytestrings should only be encountered around input/output boundaries (handling of binary fields or HTTP streams, for example). You might have to update your code to limit bytestring usage to a minimum, as Django no longer accepts bytestrings in certain code paths.

For example, reverse() now uses str() instead of force_text() to coerce the args and kwargs it receives, prior to their placement in the URL. For bytestrings, this creates a string with an undesired b prefix as well as additional quotes (str(b'foo') is "b'foo'"). To adapt, call decode() on the bytestring before passing it to reverse().

Totally unable to work on its implications, i had to go deeper into the actual django core code.

So from django 1.11 to 2.0 the encode change is as follows

'uid': urlsafe_base64_encode(force_bytes(user.pk)),

to

'uid': urlsafe_base64_encode(force_bytes(user.pk)).decode(),

and decode from

uid = force_text(urlsafe_base64_decode(uidb64))

to

 uid = urlsafe_base64_decode(uidb64).decode()

Thats it. Hope this helps someone.

*************EDIT******************

As of Django 2.2

django.utils.http.urlsafe_base64_encode() now returns a string instead of a bytestring.

And django.utils.http.urlsafe_base64_decode() may no longer be passed a bytestring.

Thanks to Hillmark for pointing it out

这篇关于Django 2,Python 3.4无法解码urlsafe_base64_decode(uidb64)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆