【问题标题】:TypeError: hash must be unicode or bytes, not NoneTypeError: hash 必须是 unicode 或 bytes,而不是 None
【发布时间】:2017-01-12 00:20:30
【问题描述】:

我正在使用 mongoengine 开发 Flask 项目。当用户注册时,使用 passlib.hash 注册代码散列到密码。当我尝试在登录身份验证中读取密码时,出现此错误。

TypeError: hash must be unicode or bytes, not None

追溯:

TypeError
TypeError: hash must be unicode or bytes, not appname.models.User

Traceback (most recent call last)

File "/*/**/***/***/appname/env/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)

File "/*/**/***/***/appname/env/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))

File "/*/**/***/***/appname/env/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)

File "/*/**/***/***/appname/env/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()

File "/*/**/***/***/appname/env/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)

File "/*/**/***/***/appname/env/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)

File "/*/**/***/***/appname/env/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()

File "/*/**/***/***/appname/env/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)

File "/*/**/***/***/appname/views.py", line 207, in login
if sha256_crypt.verify(u''+ passW,user):

File "/*/**/***/***/appname/env/lib/python2.7/site-packages/passlib/utils/handlers.py", line 567, in verify
self = cls.from_string(hash, **context)

File "/*/**/***/***/appname/env/lib/python2.7/site-packages/passlib/handlers/sha2_crypt.py", line 285, in from_string
hash = to_unicode(hash, "ascii", "hash")

File "/*/**/***/***/appname/env/lib/python2.7/site-packages/passlib/utils/__init__.py", line 617, in to_unicode
raise ExpectedStringError(source, param)

TypeError: hash must be unicode or bytes, not appname.models.User
The debugger caught an exception in your WSGI application. You can now look at the traceback which led to the error.

To switch between the interactive traceback and the plaintext one, you can click on the "Traceback" headline. From the text traceback you can also create a paste of it. For code execution mouse-over the frame you want to debug and click on the console icon on the right side.

You can execute arbitrary Python code in the stack frames and there are some extra helpers available for introspection:

dump() shows all variables in the frame
dump(obj) dumps all that's known about the object

这是我的 views.py 代码:

@app.route("/login", methods=['GET','POST'])
def login():
    if current_user.is_authenticated:
        flash("You're already registered", "info")
        return redirect(url_for('profile')+('/'+current_user.slug))

    form = LoginForm()
    passW = form.password.data

    if request.method == 'POST':
        form = LoginForm()

        if form.validate_on_submit():
            user = User.objects(email=form.email.data, password=str(passW)).first()
            if sha256_crypt.verify(passW, user):
                login_user(user, form.remember_me.data)
                slug = slugify(user.name)

                flash('We are glad you came {}.'.format(user.name),'success')
                return redirect(request.args.get('next') or url_for('profile', slug=slug))

            else:
                flash('Wrong username or password.','danger')
                return render_template("login.html", form=form, title="Cp-Login")
    return render_template("login.html", form=form, title="Cp-Login")

我们将不胜感激。

【问题讨论】:

  • 将您的完整回溯粘贴到您的问题中,并将其格式化为代码{}
  • 我添加了你问的东西。谢谢。
  • 更改代码或请求后,您的错误消息现在是 TypeError: hash must be unicode or bytes, not appname.models.User。

标签: python unicode hash flask typeerror


【解决方案1】:

正如@aison 上面所说,我必须将 objects 变量更改为 objects 字段变量作为 user.password

if sha256_crypt.verify(passW, user.password): 

还需要更改模型查询集本身。我删除了查询中的密码字段,因为密码在上面的表单验证后已经验证了 sha256_crypt 语句

修改前

user = User.objects(email=form.email.data, password=str(passW)).first()

修改后

user = User.objects(email=form.email.data).first()

@aison 建议完成其余部分的哈希验证语句

if sha256_crypt.verify(passW, user.password): 

【讨论】:

    【解决方案2】:

    我猜问题出在这里:

    user = User.objects(email=form.email.data, password=str(passW)).first()
    

    如果您的数据库找不到任何匹配的用户,用户将是无。所以你最好先用 if else 来判断用户是否存在。

    编辑

    来自 Passlib 中的文档,

    >>> # import the hash algorithm
    >>> from passlib.hash import sha256_crypt
    
    >>> # generate new salt, and hash a password
    >>> hash = sha256_crypt.encrypt("toomanysecrets")
    >>> hash
    '$5$rounds=80000$zvpXD3gCkrt7tw.1$QqeTSolNHEfgryc5oMgiq1o8qCEAcmye3FoMSuvgToC'
    
    >>> # verifying the password
    >>> sha256_crypt.verify("toomanysecrets", hash)
    True
    >>> sha256_crypt.verify("joshua", hash)
    False
    

    你的代码

    if sha256_crypt.verify(passW, user):
    

    应该是

    if sha256_crypt.verify(passW, user.password):
    

    如果您存储用户的密码,请使用 Passlib。但通常你应该使用 django 内置的authenticating 来做这样的事情。

    【讨论】:

    • 谢谢,它有帮助。我也不得不做一些改变。我现在在你的帮助下回答我的问题。 :) 再次感谢。
    猜你喜欢
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 2014-10-31
    • 2021-09-09
    • 1970-01-01
    • 2015-07-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多