为什么我的current_user在flask-login中未经过身份验证?

时间:2016-06-02 16:11:47

标签: python-3.x authentication flask flask-login

我的目标是让我的主视图(/)成为登录页面。用户登录后,将根据其角色呈现不同的页面。当我登录(/auth)时,我看到正确输入了用户名和密码。然后它会尝试呈现/,它会告诉我我的用户未经过身份验证并呈现/login。以下是描述这一点的观点:

浏览

@app.route("/login")
def login():
    return flask.render_template('login.html')

@app.route("/", methods=["GET"])
def home():
    if current_user.is_authenticated:
        if current_user.is_admin():
            return flask.render_template('admin_index.html')
        return flask.render_template('user_index.html')
    logger.info("Not authenticated. Going back to login.")
    return flask.render_template('login.html')


@app.route("/auth", methods=["POST"])
def auth():
    username = request.form['username']
    password = request.form['password']
    user = db.session.query(User).filter(User.username == username).first()
    logger.info(user)
    logger.info("{0}: {1}".format(username, password))
    print("user exists? {0}".format(str(user != None)))
    print("password is correct? " + str(user.check_password(password)))
    if user and user.check_password(password):
        user.is_authenticated = True
        login_user(user)
        return flask.redirect(url_for('home'))
    return flask.redirect(url_for('login'))

问题是在我尝试登录后,flask-login的current_user.is_authenticated总是返回False。我创建的用户已正确创建并提交到数据库。下面是我的用户模型,其中包含必要的方法,如烧瓶登录:

用户模型

class User(db.Model):
    """
    A user. More later.
    """

    __tablename__ = 'User'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(128), unique=True)
    hashed_password = db.Column(db.String(160))
    admin = db.Column(db.Boolean)

    def __init__(self, username, password="changeme123", admin=False):
        self.username = username
        self.set_password(password)
        self.admin = admin
        self.is_authenticated = False

    def is_active(self):
        return True

    def is_authenticated(self):
        return self.is_authenticated

    def is_anonymous(self):
        return False

    def is_admin(self):
        return self.admin

    def get_id(self):
        return self.id

    def __repr__(self):
        return '<User {0}>'.format(self.username)

    def set_password(self, password):
        self.hashed_password = generate_password_hash(password)

    def check_password(self, password):
        return check_password_hash(self.hashed_password, password)

以下是load_user功能:

load_user

@login_manager.user_loader
def load_user(user_id):
    try:
        return User.query.get(User.id==user_id)
    except:
        return None

为什么current_user.is_authenticated会返回False?我假设login_user(user)current_user == user成为/auth,即在ng-repeat中进行身份验证的人,但似乎情况并非如此。

2 个答案:

答案 0 :(得分:4)

您有一个名为User.is_authenticated的方法。但是,在User.__init__内,您可以设置具有相同名称的属性。

self.is_authenticated = False

这会覆盖该方法。然后,只要您检查current_user.is_authenticated,就会访问始终为假的属性。

您应该从__init__删除作业,并将is_authenticated更改为以下内容:

def is_authenticated(self):
    return True

如果由于某种原因需要它是动态的,请重命名该属性,使其不会遮挡该方法。

def is_authenticated(self):
    return self._authenticated

另一个问题是您的load_user功能。

而不是filter User.id==user_id,而是get。由于load_user正在返回User.query.get(True)而不是User.query.get(user_id),因此未返回用户。

如果您进行以下更改,它将起作用:

@login_manager.user_loader
def load_user(user_id):
    try:
        return User.query.get(user_id)
    except:
        return None

答案 1 :(得分:0)

  1. 您不必在数据库中创建is_authenticated字段
  2. Flask登录将解决此问题