web-dev-qa-db-fra.com

flask-login: je ne comprends pas comment ça marche

J'essaie de comprendre comment Flask-Login fonctionne.

Je vois dans leur documentation qu'ils utilisent une liste pré-remplie d'utilisateurs. Je veux jouer avec une liste d'utilisateurs stockés dans une base de données.

Cependant, je ne comprends pas certaines choses dans ce module Flask-Login .

@login_manager.user_loader
def load_user(userid):
    #print 'this is executed',userid
    return user(userid, 'asdf')

Ce code sera appelé à chaque demande? Ceci est utilisé pour charger tous les détails de mon objet utilisateur?

Pour l'instant, j'ai ce code:

@app.route('/make-login')
def make_login():
    username = 'asdf'
    password = 'asdf'
    user_data = authenticate(username, password)
    user_obj = user(user_data[0], user_data[1])
    login_user(user_obj)
    return render_template('make-login.html')

Quand je me connecte/me connecte, je veux me connecter.

Ma classe d'utilisateurs:

class user(object):
    def __init__(self, id, username, active=True):
        self.username = username
        self.id = id
        #self.active = active
    def is_authenticated(self):
        return True  

    def is_active(self):
        return True

    def is_anonymous(self):
        return False

    def get_id(self):
        return 5

En outre, j'ai écrit deux autres fonctions pour authentifier/enregistrer

def authenticate(username, password):

    cursor = db.cursor()
    password = md5.md5(password).hexdigest()
    try:
        query = "SELECT * FROM `users` WHERE `username` = %s AND `password` = %s"
        cursor.execute(query, (username, password))
        results = cursor.fetchall()
        #print results[0][0]
        #print "here i am"
        if not results:
            return False
        else:
            user_data = [results[0][0], results[0][1]]
            return user_data
            #self.authenticated = True
            #self.user_id = results[0][0]
            #session['username']  = results['username']
            #print type(results)
    except db.Error, e:
        return 'There was a mysql error'    

def register(username, password, email, *args):
    cursor = db.cursor()
    password = md5.md5(password).hexdigest()
    try:
        #query = "INSERT INTO `users` (`username`, `password`, `email`) VALUES ('%s', '%s', '%s')" % (username, password, email)
        query = "INSERT INTO `users` (`username`, `password`, `email`) VALUES (%s, %s, %s)"
        cursor.execute(query, (username, password, email))
        db.commit()
        return True
    except db.Error, e:
        print 'An error has been passed. %s' %e
        db.rollback()
        return False

Je ne sais pas comment faire en sorte que Flask-Login fonctionne avec MySQL. De plus, je ne sais pas si l'utilisateur est connecté. Comment puis-je obtenir l'ID utilisateur ou le nom d'utilisateur?

N'importe qui peut m'expliquer dans quelques lignes comment ceci Flask-Login fonctionne?

60
Sorin Vladu

Flask-login n'a pas réellement de backend utilisateur, il se contente de gérer le mécanisme de session pour vous aider à vous connecter et à vous déconnecter des utilisateurs. Vous devez lui dire (en utilisant des méthodes de décoration) ce qui représente un utilisateur et vous devez également savoir comment savoir si un utilisateur est "actif" ou non (car être "actif" peut signifier différentes choses dans différentes applications ).

Vous devriez lire le documentation } et vous assurer de ce qu'il fait et ne fait pas. Ici, je vais seulement me concentrer sur le câblage avec le backend de base de données.

Pour commencer, définissez un objet utilisateur; qui représente les propriétés de vos utilisateurs. Cet objet peut ensuite interroger des bases de données, ou LDAP, ou autre, et c'est le raccord qui connecte le mécanisme de connexion au backend de votre base de données.

Je vais utiliser le script exemple de connexion à cette fin.

class User(UserMixin):
    def __init__(self, name, id, active=True):
        self.name = name
        self.id = id
        self.active = active

    def is_active(self):
        # Here you should write whatever the code is
        # that checks the database if your user is active
        return self.active

    def is_anonymous(self):
        return False

    def is_authenticated(self):
        return True

Une fois que vous avez créé l'objet utilisateur, vous devez écrire une méthode qui charge l'utilisateur (en gros, crée une instance de la classe User à partir de ci-dessus). Cette méthode est appelée avec l'ID utilisateur.

@login_manager.user_loader
def load_user(id):
     # 1. Fetch against the database a user by `id` 
     # 2. Create a new object of `User` class and return it.
     u = DBUsers.query.get(id)
    return User(u.name,u.id,u.active)

Une fois que vous avez ces étapes, votre méthode de connexion fait ceci:

  1. Vérifie si le nom d'utilisateur et le mot de passe correspondent (par rapport à votre base de données) - vous devez écrire ce code vous-même.

  2. Si l'authentification a réussi, obtenez l'ID de l'utilisateur et transmettez-le à login_user()

62
Burhan Khalid

Flask-login essaiera de charger un utilisateur AVANT chaque demande. Alors oui, votre exemple de code ci-dessous sera appelé avant chaque demande. Il est utilisé pour vérifier quel identifiant est dans la session en cours et chargera l'objet utilisateur correspondant à cet identifiant.

@login_manager.user_loader
def load_user(userid):
    #print 'this is executed',userid
    return user(userid, 'asdf')        

Si vous regardez le code source de Flask-login sur github, il y a une ligne sous la fonction init_app qui va:

app.before_request(self._load_user)

Donc, avant chaque requête, la fonction _load_user est appelée. Les fonctions _load_user appellent en réalité une autre fonction "reload_user ()" en fonction de conditions. Et enfin, la fonction reload_user () appelle la fonction de rappel que vous avez écrite (load_user () dans votre exemple).

De plus, flask-login fournit uniquement le mécanisme permettant de connecter/déconnecter un utilisateur. Peu importe si vous utilisez la base de données mysql. 

14
codegeek

Conformément au document Flask-Login , un objet utilisateur doit être renvoyé. Si l'ID utilisateur n'est pas trouvé, il doit renvoyer None au lieu de Exception.

@login_manager.user_loader
def load_user(userid):
    try:
        #: Flask Peewee used here to return the user object
        return User.get(User.id==userid)
    except User.DoesNotExist:
        return None
5
beebek

Vous voudrez peut-être utiliser Flask-Security , qui associe Flask-Login à SQLAlchemy pour l’accès à la base de données et automatise une grande partie de la gestion d’enregistrement des dossiers d’utilisateur.

Le tutoriel Démarrage rapide vous permettra de démarrer. Définissez app.config ['SQLALCHEMY_DATABASE_URI'] sur votre chaîne de connexion à la base de données MySQL.

5
Steve Saporta

Voici un exemple Flask d'utilisation de login: https://bitbucket.org/leafstorm/flask-login/src/3160dbfc7cfc/example/login-example.py Vous devez utiliser @login_required pour chaque méthode nécessitant une connexion . Par exemple, 

@app.route('/make-login')
@login_required
def make_login():
    ...
0
DrSkippy