python - 无法让 @login_required 装饰器工作
问题描述
我无法让我的应用程序接受登录用户。我没有收到错误,并且还没有实现密码的逻辑。我正在按照readthedocs中的步骤操作,但无法解决。
预期: 用户登录并访问需要登录的页面。
实际: 用户登录但在尝试访问需要登录的页面时被重定向到登录页面。
我的代码中遗漏了什么?
编辑:我的load_user(user_id)
方法总是不返回,这是为什么呢?
EDIT2:我开始意识到我的用户对象只在登录方法中创建。我必须在代码中进行哪些更改才能使用户可以通过其他方法访问?
from flask import Flask, render_template, request, redirect, session
from flask_login import LoginManager, login_required, login_user, UserMixin, logout_user
from werkzeug.security import generate_password_hash
app = Flask(__name__)
app.secret_key = "Redacted"
login_manager = LoginManager()
login_manager.init_app(app)
class User:
def __init__(self, name):
self.name = name
def is_authenticated(self):
return True
def is_active(self):
return True
def is_anonymous(self):
return False
def get_id(self):
return unicode(1)
@login_manager.user_loader
def load_user(user_id):
try:
return User.get_id(user_id)
except:
return None
login_manager.login_view = 'login'
@app.route('/')
@login_required
def index():
return render_template('index.html')
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == "POST":
name = request.form.get("username")
password = generate_password_hash(request.form.get("password"))
if not name:
print("debug: did not recieve a name")
user = User(name)
login_user(user)
return redirect('/')
else:
return render_template('login.html')
@app.route('/logout', methods=['GET'])
@login_required
def logout():
logout_user()
return redirect('/')
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')
解决方案
文档和您的代码之间存在一些差异。
你的代码:
return User.get_id(user_id)
不返回用户实例,而是返回 ID。你也可能有其他错误。然后,如果出现异常,则返回 None:
except:
return None
但否则异常会被忽视,这不是一件好事。我建议您至少在开发模式下提出异常,或者至少在某处记录消息。如果忽略发生的异常,这只会使程序更难调试。
我个人使用类似的东西:
if current_user.is_authenticated:
return redirect(url_for('index'))
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(username=form.username.data).first()
if user is None or not user.check_password(form.password.data):
errors.append('Invalid username or password')
# log failure
return redirect(url_for('cp_bp.login'))
else:
login_user(user)
这个想法是通过名称(使用 ORM FlaskAlchemy)定位用户,然后检查密码,然后登录用户。
您可能知道,但您的代码尚未完成。您正在登录用户而不检查密码是否正确。
当您在 Flask 中有一个有效会话时,您可以使用current_user
来引用登录用户。
你像这样导入它(连同其他需要的方法):
from flask_login import LoginManager, login_required, current_user, login_user, logout_user
然后,您可以根据您对 User 模型的个人实现,在代码中使用类似:current_user.name
或其他地方的属性。current_user.id
推荐阅读
- javascript - 由 Electron Builder 生成的二进制文件的操作系统特定目录
- amazon-ec2 - AWS Lambda EC2-Instances 客户端超时错误
- php - 如何遍历自定义分类类别
- android - Android Room 报错 ProductDatabase_Impl 不是抽象的,没有覆盖 ProductDatabase 中的抽象方法 getProductDao()
- java - CrudRepository 接口 - 找不到 bean
- google-cloud-platform - 在 GCP 上配置 HTTPS 负载平衡器时,后端服务中的几个 VM 实例运行状况不佳
- spring-boot - 使用 Schema Registary 和 Kafka Restproxy 向 Kafka 发送消息的 Rest 模板
- python - 为什么当我尝试删除特定行时我的价格列被替换?
- r - 将包含分号的excel公式转换为ar公式
- ldap - 是否可以通过 HTTP 代理向 LDAP 服务器发送请求?