有人可以帮我确定Bcrypt失败的原因(ValueError:密码必须是非空的)

时间:2016-01-04 21:31:01

标签: python flask bcrypt

我有一个小烧瓶应用程序,我目前正在重写并更改每个烧瓶惯例的目录树。在之前的应用程序中,我能够使烧瓶Bcrypt工作,但在这个新结构中它似乎不起作用。

以下是我在models.py

中提供的代码片段
from blackduckflock import app, db, bcrypt


class User(db.Model, flask_login.UserMixin):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(50))
    password = db.Column(db.String(250))

    def __init__(self, username='', password=''):
        self.username = username


        # self.password = password

        #------The code below fails while the code above works just fine ------------

        #self.password = bcrypt.generate_password_hash(password)

    def __repr__(self):
        return '<User %r>' % self.username

bcrypt.generate_password(ValueError: Password must be non-empty)失败。由于某种原因,Create表单不会与请求保持一致,也不会转移到bcrypt。 code.interact(local=locals())表示正在传递默认的''参数而不是实际的表单值。如果没有bcrypt生成,代码就可以正常运行并创建用户。

我不确定为什么会这样,但有人有任何想法吗?

这是__init__.py

中的blackduckflock/blackduckflock/__init__.py个文件
import os
from flask import Flask
from flask.ext.bcrypt import Bcrypt
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.script import Manager
from flask.ext.migrate import Migrate, MigrateCommand

app = Flask(__name__)
bcrypt = Bcrypt(app)
db = SQLAlchemy(app)
manager = Manager(app)
migrate = Migrate(app,db)
manager.add_command('db', MigrateCommand)

file_path = os.path.join(os.path.dirname(__file__), 'static/images/')

import blackduckflock.views
import blackduckflock.models
import blackduckflock.forms
import blackduckflock.admin

可能是什么问题?

---------------------编辑(最小,完整,示例)------------------

树目录:

blackduckflock/
   blackduckflock/
     - __init__.py
     - models.py
     - forms.py
     - views.py
     - admin.py
   - blackduckflock.py
   - config.py

blackduckflock.py:

from blackduckflock import app

app.config.from_object('config')

app.run()

初始化的.py

from flask import Flask
from flask.ext.bcrypt import Bcrypt
from flask.ext.sqlalchemy import SQLAlchemy

app = Flask(__name__)
bcrypt = Bcrypt(app)
db = SQLAlchemy(app)

import blackduckflock.admin
import blackduckflock.views
#import blackduckflock.models
#import blackduckflock.forms

admin.py:

class MyAdminIndexView(AdminIndexView):
    pass

admin = Admin(app, name='BlackDuck Flock',        
              index_view=MyAdminIndexView(),  
              template_mode='bootstrap3')


class UserView(ModelView):
    def is_accessible(self):
        return flask_login.current_user.is_authenticated

admin.add_view(UserView(User, db.session))

models.py:

from blackduckflock import app, db, bcrypt
import flask.ext.login as flask_login

class User(db.Model, flask_login.UserMixin):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(50))
    password = db.Column(db.String(250))

    def __init__(self, username='', password=''):
       self.username = username
       # self.password = password
       # code.interact(local=locals())
       self.password = bcrypt.generate_password_hash(password)

    def __repr__(self):
        return '<User %r>' % self.username

views.py:

import flask.ext.login as flask_login
from blackduckflock import db, app
from blackduckflock.models import User

login_manager = flask_login.LoginManager()
login_manager.init_app(app)

@login_manager.user_loader
def load_user(user_id):
     return db.session.query(User).get(user_id)

2 个答案:

答案 0 :(得分:1)

除非确保没有将空密码传递给generate_password_hash函数,否则不能为User类提供可选参数:

class User:
    def __init__(self, username='', password=''):
        self.username = username

        if password != '':
             self.password = bcrypt.generate_password_hash(password)

或者只是删除可选参数,并强制执行:

class User:
    def __init__(self, password, username=''):
        self.username = username

        self.password = bcrypt.generate_password_hash(password)

这很重要,因为无论何时尝试使用空参数初始化类,因为它们是可选的,如下所示:

user = User()

它会失败,因为它会尝试传递密码=&#39;&#39;到bcrypt.generate_password_hash(密码),它会引发错误。

答案 1 :(得分:1)

我通过实现下面显示的事件回调解决了我的困境。

@listens_for(User, 'before_insert')
def bcrypt_password(mapper, connection, target):
   target.password = bcrypt.generate_password_hash(target.password)