Flask登录名login_user未设置is_authenticated

时间:2019-05-11 12:11:18

标签: python flask flask-login

(第一次)使用Flask Login时,并在我遇到的每个教程示例中,在正确发布凭据,调用login_user()并重定向到受保护的login_required路由之后,我仍然收到401未经授权的响应。仅当我将is_authorised属性显式设置为True时,它才起作用。但这似乎没有必要,而且我找不到任何教程示例都可以做到这一点。我在俯视什么?下面的示例代码。谢谢!

from flask import Flask, render_template, url_for, jsonify, session, redirect, request
from flask_login import LoginManager, login_required, login_user, current_user

login_manager = LoginManager()
app = Flask(__name__)
app.secret_key = b'_5#y2L"F4Q8z\n\xecgwefweligli]/'
login_manager.init_app(app)

class User:
    _users = {
        'me': 'mypass'
    }

    _active_users = {}

    def __init__(self, user_id):
        self.user_id = user_id
        self.password = self._users[user_id]
        self._authenticated = False
        self._active = True

    @property
    def is_active(self):
        return self._active

    @property
    def is_authenticated(self):
        return self._authenticated

    @is_authenticated.setter
    def is_authenticated(self, value):
        if value:
            self._authenticated = True
        else:
            self._authenticated = False

    @property
    def is_anonymous(self):
        return False

    def get(user_id):
        if user_id in User._active_users:
            return User._active_users[user_id]
        if user_id in User._users:
            User._active_users[user_id] = User(user_id)
            return User._active_users[user_id]
        return None

    def get_id(self):
        return self.user_id

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

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        u = User.get(request.form['username'])
        app.logger.debug(u)
        if u and u.password == request.form['password']:
            app.logger.debug('authenticated')
            r = login_user(u)
            u.is_authenticated = True  # HERE: this shouldn't be necessary?
            app.logger.debug(u.is_authenticated)
            app.logger.debug(current_user.is_authenticated)
            return redirect(url_for('index'))
        return redirect(url_for('login'))
    return render_template('login.html')

@app.route('/')
@login_required
def index():
    return render_template('main.html')

当我移除时:

u.is_authenticated = True

用户未通过身份验证。我看过了login_user()的源代码,它似乎没有设置is_authenticated。我做对了吗?我很困惑,因为没有文档/教程包括上述内容,但是所有人都声称可以正常工作。

1 个答案:

答案 0 :(得分:0)

您需要显式设置is_authenticated的原始代码,因为从一个请求到下一个请求,每次都会创建一个新的User对象实例,因此丢失了已经通过身份验证的用户的信息。

为避免丢失此信息,我们需要一个地方来存储它。虽然Flask-login提供了一个UserMixin类,该类提供了默认的实现,但是您可以在User模型中添加经过身份验证的字段:

authenticated = db.Column(db.Boolean, default=False)

当用户登录时,应将身份验证更改为true并将更改保存在数据库中;当用户注销时,应将身份验证更改为false并将更改保存在数据库中。

is_authenticated函数将与此类似:

@property
def is_authenticated(self):
    return self.authenticated

请找到此tutorial