更新时间:2023-12-04 10:05:16
更新: 这里的问题是
由于Flask-Login的更新版本(0.2.2)不再是一个问题。看看
如果您使用的是旧版本,请继续阅读。
static_url_path =
。对于Flask-Login的工作,你不能有一个空字符串 static_url_path
。
$ b 以下几行显示:
if(current_app.static_url_path is not None and
request.path.startswith(current_app.static_url_path)
):
#为静态页面加载一个匿名用户
_request_ctx_stack.top。 user = self.anonymous_user()
return
由于您的 static_url_path $ c>是
if条件的计算结果为
True
,因为您访问的每个页面就像一个静态页面,因此Flask-Login总是加载一个匿名用户,而不是conti nu使用 load_user
回调)另外不要忘了取消注释#login_manager.login_view =login
如果您仍然想使用应用程序本身的根文件夹作为静态文件夹,请查看这个解决方案,使用 SharedDataMiddleware :
app.debug = True
如果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(HOS t =0.0.0.0)
I am trying to build a super simple web app for my own use. I'll be the only user, so I don't feel the need to involve a database for user management. I'm trying to use flask-login, but even though my call to login_user
succeeds, I'm still met with a 401-Unauthorized page after the redirect to a page with @login_required
. Here is the entirety of my app:
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)
I've verified that the login actually succeeds (login_user
returns true) and that load_user
is returning the nathan
object.
[EDIT] Also, I'm currently using the Flask development server, in case that's relevant.
Not sure where I'm going wrong. Thanks in advance!
Update:
Since a newer version(0.2.2) of Flask-Login this is no more an issue. Check out the changes in this commit.
If you are using an older version, read on.
The problem here is static_url_path=""
. For Flask-Login to work you can not have an empty string static_url_path
.
The following lines in the Flask-Login source(older version) reveal this:
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
Since your static_url_path
is ""
the if condition evaluates to True
, because of which every page you visit acts like a static page, and hence Flask-Login always loads an anonymous user, instead of continuing to load the actual user(using the load_user
callback).
Also do not forget to uncomment #login_manager.login_view = "login"
If you still want to use the root folder of the app itself as the static folder, take a look at this solution, using 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")