2013-05-18 8 views
5

Ich versuche, eine super einfache Web-App für meinen eigenen Gebrauch zu bauen. Ich werde der einzige Benutzer sein, so dass ich keine Datenbank für die Benutzerverwaltung benötige. Ich versuche flask-login zu verwenden, aber obwohl mein Anruf bei login_user erfolgreich ist, bin ich immer noch mit einer 401-Nicht autorisierten Seite nach der Weiterleitung auf eine Seite mit @login_required konfrontiert. Hier ist die Gesamtheit meiner App:Flask-Login mit statischen Benutzer immer 401- Unauthorized

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) 

ich überprüft haben, dass die Anmeldung erfolgreich tatsächlich (login_user Renditen true) und dass load_user kehrt das nathan Objekt.

[EDIT] Außerdem verwende ich derzeit den Flask-Entwicklungsserver, falls das relevant ist.

Nicht sicher, wo ich falsch liege. Danke im Voraus!

+0

Ich bin mir nicht sicher, dass Sie Flask-Login ohne Datenbank verwenden können. Es benötigt eine Möglichkeit, um Ihre Sitzung zu speichern. – computmaxer

+0

Ich dachte, Session-Informationen wurden alle in Cookies gespeichert, keine Datenbank. – gnathan

+0

Ich würde vorschlagen, Cookies ein wenig mehr zu lesen. Kurz gesagt, Cookies sind Dinge, die der Browser pro Domäne speichert, die mit jeder Anfrage an diese Domäne gesendet werden. Sitzungscookies bestehen einfach aus einer Sitzungs-ID, für die die Anwendung nach dem Empfang der Anfrage verantwortlich ist. Die Anwendung muss noch einige Informationen über die Sitzung (z. B. Ablaufzeit) speichern, die der Sitzungs-ID entsprechen. Flask-login erledigt das alles für Sie, aber es braucht eine Möglichkeit, diese Sitzungen zu speichern. – computmaxer

Antwort

4

Update:

Da eine neuere Version (0.2.2) von Flask Login dies nicht mehr ein Problem. Überprüfen Sie die Änderungen in this Commit.

Wenn Sie eine ältere Version verwenden, lesen Sie weiter.


Das Problem ist hier static_url_path="". Damit Flask-Login funktioniert, können Sie keine leere Zeichenfolge static_url_path haben.

Die following lines in der Flasche Login für Quelle (ältere Version) dieses offenbaren:

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 

Da Ihr static_url_path ist "" die, wenn Bedingung das Ergebnis True, weil von denen jede Seite, die Sie wirkt wie eine statische Seite besuchen Daher lädt Flask-Login immer einen anonymen Benutzer, anstatt den aktuellen Benutzer zu laden (unter Verwendung des Rückrufs load_user).


Vergessen Sie auch nicht #login_manager.login_view = "login"


Kommentar- Wenn Sie noch den Stammordner der App selbst als statische Ordner, werfen Sie einen Blick auf this Lösung verwenden möchten, mit 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") 
+1

Wow, große Antwort. Vielen Dank! Die SharedDataMiddleWare-Lösung funktioniert auch gut für mich. – gnathan

+0

Sie sind herzlich willkommen, froh zu helfen! –

+1

Sieht aus wie es in der neuesten Version (0.2.7) von Flask-Login behoben werden kann. Ich sehe keinen Verweis auf den statischen Dateipfad in dieser Version. – craigb

Verwandte Themen