问题描述
在调用login_user(user)
函数之后,应该对current_user进行身份验证。
尝试进行以下操作时:print(flask_login.current_user.is_authenticated)
登录后立即返回 TRUE ,但在下一页加载后立即返回 FALSE 。
总结:用户身份验证状态不是持久性的。
因此,无法访问受@flask_login.login_required
装饰器保护的页面(在@app.route
下面),并且将我重定向到@login_manager.unauthorized_handler
页面。
据我了解,Flask框架应该设置cookie或在包含某种身份验证的标头中发送某种信息。我还尝试使用flask的“会话”模块,也尝试使用“ g”模块,但是它们产生了完全不同的错误。
我从https://github.com/maxcountryman/flask-login抄袭的以下版本的代码,仅使用我下面的内容。但是由于某种原因,我的版本无法正常工作。
出于此测试阶段的目的,我列出了包含用户的python字典的列表,因此我不必对用于存储信息的Firebase数据库进行多个不必要的调用。
这是登录管理器的设置部分,包括我的UserMixin类的副本:
app.secret_key = 'dummysecretkey'
login_manager = flask_login.LoginManager()
login_manager.init_app(app)
class User(flask_login.UserMixin):
pass
这是用户结构的示例:
{
'email': 'email@domain.com','password': 'password','username': 'user01'
...*other fields*...
}
以下是登录管理器的路由:
@login_manager.user_loader
def user_loader(username):
for entries in users:
if entries['username'] not in users:
return
for entries in users:
if entries['username'] == username:
user = User()
user.id = entries['username']
return user
@login_manager.request_loader
def request_loader(request):
username = request.form.get('username')
try:
for entries in users:
if entries['username'] == username:
user = User()
user.id = entries['username']
user.is_authenticated = request.form['password'] == entries['password']
return user
except:
return None
@app.route('/login',methods=['GET','POST'])
def login():
if request.method == 'GET':
return render_template('login.html')
uname = request.form['uname']
psw = request.form['psw']
for entries in users:
if uname == entries['username'] and psw == entries['password']:
user = User()
user.id = uname
flask_login.login_user(user)
print(flask_login.current_user.is_authenticated)
return redirect(url_for('addnew'))
return 'Bad login'
需要身份验证的示例路由:
@app.route('/addnew')
@flask_login.login_required
def addnew():
return render_template("addnew.html")
尽管密码比较存在缺陷(我知道它们是不安全的),但有人可以指出上述代码中的缺陷还是提出一种实现登录身份验证的替代方法?
解决方法
您的代码让我有些困惑。
从Flask登录文档中:
有时您想不使用cookie(例如使用标头值或作为查询参数传递的api键)登录用户。在这种情况下,您应该使用request_loader回调。
但是我知道您想使用基于cookie的登录名?
因此,您不应使用request_loader
。
此外,为什么还要在登录路径中实例化一个新的User
?登录名应将登录数据与现有用户进行比较。
我建议您“手动”实例化用户并将其放在这样的列表中:
users = []
a = User()
a.name = "name_a"
a.id = "id_a"
users.append(a)
...
然后修改您的user_loader,以将表单中的登录数据与现有数据进行比较。
Miguel Grinberg提供了一个出色的Flask教程,该教程还解释了用户登录:
https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world