Porównaj ceny domen i usług IT, sprzedawców z całego świata

Dlaczego mój current_user nie uwierzytelnia się przy logowaniu do flask?


Moim celem jest, aby mój widok główny (
/
) był stroną logowania. Gdy użytkownik jest zalogowany, wyświetlana jest inna strona w zależności od jego roli. Kiedy loguję się (
/ auth
), widzę, że nazwa użytkownika i hasło są poprawne. Następnie próbuje renderować
/
, gdzie informuje mnie, że mój użytkownik nie jest uwierzytelniony, i renderuje
/ login
. Oto opinie, które to opisują:

Wyświetlenia
>
@app.route("/login")
def login():
return flask.render_template('login.html')@app.route("/", methods=["GET"])
def home():
if current_user.is_authenticated:
if current_user.is_admin():
return flask.render_template('admin_index.html')
return flask.render_template('user_index.html')
logger.info("Not authenticated. Going back to login.")
return flask.render_template('login.html')
@app.route("/auth", methods=["POST"])
def auth():
username = request.form['username']
password = request.form['password']
user = db.session.query(User).filter(User.username == username).first()
logger.info(user)
logger.info("{0}: {1}".format(username, password))
print("user exists? {0}".format(str(user != None)))
print("password is correct? " + str(user.check_password(password)))
if user and user.check_password(password):
user.is_authenticated = True
login_user(user)
return flask.redirect(url_for('home'))
return flask.redirect(url_for('login'))

Problem polega na tym, że
current_user.is_authenticated
flask-login zawsze zwraca
False
po próbie zalogowania. Utworzony przeze mnie użytkownik jest poprawnie utworzony i zapisany w bazie danych. Poniżej znajduje się mój model użytkownika z wymaganymi metodami zgodnie z logowaniem do flask:

Model użytkownika
>
class User(db.Model):
"""
A user. More later.
""" __tablename__ = 'User'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(128), unique=True)
hashed_password = db.Column(db.String(160))
admin = db.Column(db.Boolean) def __init__(self, username, password="changeme123", admin=False):
self.username = username
self.set_password(password)
self.admin = admin
self.is_authenticated = False def is_active(self):
return True def is_authenticated(self):
return self.is_authenticated def is_anonymous(self):
return False def is_admin(self):
return self.admin def get_id(self):
return self.id def __repr__(self):
return '<User {0}>'.format(self.username) def set_password(self, password):
self.hashed_password = generate_password_hash(password) def check_password(self, password):
return check_password_hash(self.hashed_password, password)

Oto funkcja
load_user
:

load_user
>
@login_manager.user_loader
def load_user(user_id):
try:
return User.query.get(User.id==user_id)
except:
return None

Dlaczego
current_user.is_authenticated
zwraca wartość
False
? Założyłem, że
login_user (user)
zrobi
current_user == user
, czyli ktokolwiek uwierzytelni się w
/ auth
, ale wygląda na to, że nie tak sposób.
Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Masz metodę o nazwie
User.is_authenticated
. Jednak wewnątrz
User .__ init__
ustawiasz atrybut o tej samej nazwie.
self.is_authenticated = False

To przesłania metodę. Następnie za każdym razem, gdy zaznaczysz
current_user.is_authenticated
, uzyskasz dostęp do atrybutu, który jest zawsze fałszywy.
Musisz usunąć przypisanie z
__init__
i zmienić
is_authenticated
na następujące:
def is_authenticated(self):
return True

Jeśli z jakiegoś powodu chcesz, aby był dynamiczny, zmień nazwę atrybutu, aby nie przesłaniał metody.
def is_authenticated(self):
return self._authenticated

Inny problem dotyczy funkcji
load_user
.
Zamiast
filter
ing for
User.id == user_id
,
get
ting it. Użytkownik nie wrócił, ponieważ
load_user
zwraca
User.query.get (True)
zamiast
User.query.get (user_id)
.
Jeśli wprowadzisz następującą zmianę, zadziała:
@login_manager.user_loader
def load_user(user_id):
try:
return User.query.get(user_id)
except:
return None

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się