python - 烧瓶登录 login_user 未设置 is_authenticated
问题描述
使用 Flask Login(第一次)并按照我遇到的每个教程示例,在正确发布凭据、调用 login_user() 并重定向到受保护的 login_required 路由后,我仍然收到 401 Unauthorized 响应。只有当我明确地将 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。我做对了吗?我只是感到困惑,因为没有文档/教程包含上述行,但都声称可以正常工作。
解决方案
您的原始代码需要显式设置 is_authenticated ,因为从一个请求到下一个请求,每次都会创建一个 User 对象的新实例,因此用户已经通过身份验证的信息会丢失。
为了避免丢失这些信息,我们需要一个地方来存储它。虽然 Flask-login 提供了一个 UserMixin 类来提供默认实现,但您可以在 User 模型中添加 authenticated 字段:
authenticated = db.Column(db.Boolean, default=False)
当用户登录时,您应该将authenticated 更改为true 并将更改保存在数据库中,当用户注销时,您应该将authentication 更改为false 并将更改保存在数据库中。
is_authenticated 函数将与此类似:
@property
def is_authenticated(self):
return self.authenticated
请找到本教程。
推荐阅读
- json - 如何使用打字稿创建新的 JSON 树?
- python - 正则表达式的问题应用于 Python 中的特定字符串,但在其他“任何地方”都可以正常工作
- ios - 拖放 UICollectionView 单元格重用问题
- postgresql - EMS SQL Manager for PostgreSQL query file location
- c++ - 将向量加载到大小不匹配的 AVX2 寄存器中
- java - 为什么用户输入双打不接受与常规双打相同的参数?
- ios - 如何在swift 5中将.txt文件json读入字典
- java - Heroku 应用程序使用 s3 上传图片
- android - 当 EditText 处于非活动状态时如何设置提示位置
- google-cloud-platform - 如何从 Terraform / Pulumi 访问 Cloud Run 服务 IP 以动态创建 A 记录?