Flask-用静态用户登录总是产生401-未授权 [英] Flask-login with static user always yielding 401- Unauthorized

查看:880
本文介绍了Flask-用静态用户登录总是产生401-未授权的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图建立一个超级简单的网络应用程序,供我自己使用。我将是唯一的用户,所以我不觉得需要涉及数据库用户管理。我正在尝试使用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
$ b $ 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()
返回重定向(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(索引))
else:
flash('不正确的用户名或密码。再试一次。','error')

return render_template(login.html);
$ b $ if if __name__ ==__main__:
app.run(host =0.0.0.0,debug = True)

我已经验证了登录成功( login_user 返回true),并且 load_user 返回 nathan 对象。



另外,目前正在使用Flask开发服务器,以防万一。



不知道哪里出错了。

解决方案

更新:

由于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 是 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")

这篇关于Flask-用静态用户登录总是产生401-未授权的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆