(第一次)使用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。我做对了吗?我很困惑,因为没有文档/教程包括上述内容,但是所有人都声称可以正常工作。
答案 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。