我正在与Mongoengine合作进行Flask项目。用户注册时,使用passlib.hash将散列为密码的代码注册为password。当我尝试在登录身份验证中读取密码时,出现此错误。
TypeError:哈希必须是unicode或字节,而不是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")
任何帮助将不胜感激。
最佳答案
我猜问题出在这里:
user = User.objects(email=form.email.data, password=str(passW)).first()
如果您的数据库找不到任何匹配的用户,则该用户将为none。因此,最好使用其他方式判断用户是否首先存在。
编辑
从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来执行类似的操作。