gna*_*han 7 python flask flask-login
我正在尝试构建一个超级简单的Web应用程序供我自己使用.我将是唯一的用户,所以我觉得不需要涉及用户管理的数据库.我正在尝试使用flask-login,但即使我的调用login_user成功,在重定向到页面后,我仍然遇到了401-Unauthorized页面@login_required.这是我的整个应用程序:
from flask import Flask, render_template, request, flash, redirect, url_for
from flask.ext.login import LoginManager, login_user, logout_user, current_user, login_required, UserMixin
app = Flask(__name__, static_url_path="")
app.secret_key = "[redacted]"
login_manager = LoginManager()
login_manager.init_app(app)
#login_manager.login_view = "login"
class User(UserMixin):
def __init__(self, id):
self.id = id
nathan = User('nathan')
@login_manager.user_loader
def load_user(userid):
if userid == 'nathan':
return nathan
else:
return None
@app.route("/logout")
@login_required
def logout():
logout_user()
return redirect(url_for('login'))
@app.route('/')
@login_required
def index():
return render_template('index.html')
@app.route("/login", methods=["GET", "POST"])
def login():
if request.method == 'POST':
if request.form['username'] == 'nathan'\
and request.form['password'] == '[redacted]':
login_user(nathan, remember=True)
flash('logged in...', 'success')
return redirect(request.args.get("next") or url_for("index"))
else:
flash('Incorrect username or password. Try again.', 'error')
return render_template("login.html");
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
Run Code Online (Sandbox Code Playgroud)
我已经验证登录实际上成功(login_user返回true)并load_user返回nathan对象.
[编辑]此外,我正在使用Flask开发服务器,以防相关.
不知道我哪里出错了.提前致谢!
更新:
自从 Flask-Login 的更新版本(0.2.2)以来,这不再是问题。查看此提交中的更改。
如果您使用的是旧版本,请继续阅读。
这里的问题是static_url_path=""。为了让 Flask-Login 正常工作,你不能有一个空字符串static_url_path。
Flask-Login 源代码(旧版本)中的以下几行揭示了这一点:
if (current_app.static_url_path is not None and
request.path.startswith(current_app.static_url_path)
):
# load up an anonymous user for static pages
_request_ctx_stack.top.user = self.anonymous_user()
return
Run Code Online (Sandbox Code Playgroud)
由于您的static_url_pathis ""if 条件评估为True,因此您访问的每个页面都像静态页面一样,因此 Flask-Login 始终加载匿名用户,而不是继续加载实际用户(使用回调load_user)。
也不要忘记取消注释#login_manager.login_view = "login"
如果您仍然想使用应用程序本身的根文件夹作为静态文件夹,请使用SharedDataMiddleWare查看此解决方案:
app.debug = True
if app.config['DEBUG']:
from werkzeug import SharedDataMiddleware
import os
app.wsgi_app = SharedDataMiddleware(app.wsgi_app, {
'/': os.path.dirname(__file__)
})
if __name__ == "__main__":
app.run(host="0.0.0.0")
Run Code Online (Sandbox Code Playgroud)