Outils pour utilisateurs

Outils du site


python:flask:flask_login

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentes Révision précédente
Prochaine révision
Révision précédente
python:flask:flask_login [2022/10/28 18:30]
marclebrun [Initialisation]
python:flask:flask_login [2022/10/30 04:50] (Version actuelle)
marclebrun [Login]
Ligne 13: Ligne 13:
 **UserMixin** : **UserMixin** :
  
-<code python>+<code python ​app/​models/​user.py>
 from flask_login import UserMixin from flask_login import UserMixin
 +from werkzeug.security import generate_password_hash,​ check_password_hash
  
 class User(UserMixin,​ db.Model): class User(UserMixin,​ db.Model):
Ligne 31: Ligne 32:
   * ''​is_anonymous''​   * ''​is_anonymous''​
   * ''​get_id()''​   * ''​get_id()''​
 +
 +Implémenter la propriété **password** qui sera en **écriture seule**,
 +en effet on peut seulement écrire un nouveau password mais jamais le
 +relire. L'​écriture du password assigne le **hash** de la valeur donnée
 +au champ **password_hash** :
 +
 +<code python app/​models/​user.py>​
 +    @property
 +    def password(self):​
 +        raise AttributeError('​password is not a readable attribute'​)
 +    ​
 +    @password.setter
 +    def password(self,​ password):
 +        self.password_hash = generate_password_hash(password)
 +</​code>​
 +
 +Implémenter la méthode **verify_password** :
 +
 +<code python app/​models/​user.py>​
 +    def verify_password(self,​ password):
 +        return check_password_hash(self.password_hash,​ password)
 +</​code>​
  
 ===== Initialisation ===== ===== Initialisation =====
Ligne 36: Ligne 59:
 Initialiser le **LoginManager** lors de la création de l'​application : Initialiser le **LoginManager** lors de la création de l'​application :
  
-<code python>+<code python ​app/​__init__.py> 
 +from flask       ​import Flask
 from flask_login import LoginManager from flask_login import LoginManager
  
Ligne 57: Ligne 81:
 aura besoin de charger un utilisateur sur base de son identifiant. aura besoin de charger un utilisateur sur base de son identifiant.
  
-<code python>+<code python ​app/​__init__.py> 
 +# ... 
 + 
 +from app.models.user import User 
 + 
 +# ... 
 @login_manager.user_loader @login_manager.user_loader
 def load_user(user_id):​ def load_user(user_id):​
-    # ... 
     ​     ​
     # Lecture de l'​utilisateur depuis la base de données     # Lecture de l'​utilisateur depuis la base de données
Ligne 67: Ligne 96:
     ​     ​
     return User.query.get(int(user_id))     return User.query.get(int(user_id))
-</​code>​ 
- 
-===== Login ===== 
- 
-<code python> 
-</​code>​ 
- 
-===== Protection d'une route ===== 
- 
-Avec le décorateur **@login_required** 
- 
-:!: Il est important de mettre les deux décorateurs dans cet ordre. 
- 
-<code python> 
-from flask_login import login_required 
- 
-@app.route('/​secret'​) 
-@login_required 
-def secret(): 
-    return 'Seuls les utilisateurs authentifiés verront ceci.' 
 </​code>​ </​code>​
  
 ===== Formulaire de login ===== ===== Formulaire de login =====
  
-<code python>+<code python ​app/​forms/​auth.py>
 from flask_wtf import FlaskForm from flask_wtf import FlaskForm
 from wtforms import StringField,​ PasswordField,​ BooleanField,​ SubmitField from wtforms import StringField,​ PasswordField,​ BooleanField,​ SubmitField
Ligne 104: Ligne 113:
     submit ​     = SubmitField('​Log In')     submit ​     = SubmitField('​Log In')
 </​code>​ </​code>​
 +
 +===== Login =====
 +
 +<code python app/​controllers/​auth.py>​
 +from flask           ​import Blueprint
 +from flask           ​import request
 +from flask           ​import render_template,​ redirect, url_for, flash
 +from flask_login ​    ​import login_user
 +from app.forms.auth ​ import LoginForm
 +from app.models.user import User
 +
 +auth = Blueprint('​auth',​ __name__)
 +
 +@auth.route('/​login',​ methods=['​GET',​ '​POST'​])
 +def login():
 +    form = LoginForm()
 +    ​
 +    # Si le formulaire a été posté (submit) et que son contenu
 +    # a passé toutes les validations
 +    if form.validate_on_submit():​
 +    ​
 +        # Si l'​utilisateur a cliqué sur "​Login"​
 +        if form.submit.data:​
 +        ​
 +            # Rechercher l'​utilisateur selon l'​email entré
 +            user = User.query.filter_by(email = form.email.data).first()
 +        ​
 +            # Si l'​utilisateur est trouvé, et que son mot de passe correspond
 +            if user is not None and user.verify_password(form.password.data):​
 +            ​
 +                # Prendre en compte la connexion de l'​utilisateur.
 +                # Si '​remember_me'​ vaut True, un cookie sera ajouté afin de
 +                # conserver la connexion active.
 +                login_user(user,​ form.remember_me.data)
 +                flash(u"​Welcome,​ <​b>​%s</​b>​ !" % user.name, "​success"​)
 +            ​
 +                # Retourner une redirection
 +                # - soit vers la page '​suivante'​ si le login provient d'une
 +                #   ​tentative d'​accès à une page protégée
 +                # - soit vers la page d'​accueil
 +                next = request.args.get('​next'​)
 +                if next is None or not next.startswith('/'​):​
 +                    next = url_for('​main.home'​)
 +                return redirect(next)
 +            ​
 +            # Si l'​utilisateur n'est pas trouvé, on ajoute un message flash
 +            # avant de retourner au formulaire
 +            flash(u"​Invalid username or password.",​ "​error"​)
 +        ​
 +    # Rendu du formulaire dans tous les cas non traités ci-dessus
 +    return render_template('​auth/​login.html',​ form = form)
 +</​code>​
 +
 +===== Logout =====
 +
 +<code python>
 +from flask_login import logout_user,​ login_required
 +
 +@auth.route('/​logout'​)
 +@login_required
 +def logout():
 +    logout_user()
 +    flash(u"​You have been logged out.", "​success"​)
 +    return redirect(url_for('​main.home'​))
 +</​code>​
 +
  
 ===== Objet current_user ===== ===== Objet current_user =====
Ligne 109: Ligne 184:
 La variable ''​current_user''​ est définie par **Flask-Login**,​ La variable ''​current_user''​ est définie par **Flask-Login**,​
 et elle disponible dans les templates et dans les vues. et elle disponible dans les templates et dans les vues.
 +
 +Lorsqu'​aucun utilisateur n'est connecté, ''​current_user''​ contient
 +un objet dont la propriété ''​is_authenticated''​ vaut **False**
 +
 +Lorsqu'​un utilisateur est connecté, ''​current_user''​ contient un
 +objet de la classe **User**.
 +
 +<code python>
 +from flask_login import current_user
 +
 +# ...
 +
 +if current_user.is_authenticated:​
 +    print("​Hello %s !" % current_user.name)
 +</​code>​
  
 On peut afficher le lien **Log In** ou **Log Out** en fonction On peut afficher le lien **Log In** ou **Log Out** en fonction
-de l'​état de l'​utilisateur (connecté ou non) :+de l'​état de l'​utilisateur (connecté ou non):
  
 <code html> <code html>
Ligne 119: Ligne 209:
   <a href="​{{ url_for('​auth.login'​) }}">​Log In</​a>​   <a href="​{{ url_for('​auth.login'​) }}">​Log In</​a>​
 {% endif %} {% endif %}
 +</​code>​
 +
 +===== Protection d'une route =====
 +
 +Avec le décorateur **@login_required**
 +
 +:!: Il est important de mettre les deux décorateurs dans cet ordre.
 +
 +<code python>
 +from flask_login import login_required
 +
 +@app.route('/​secret'​)
 +@login_required
 +def secret():
 +    return 'Seuls les utilisateurs authentifiés verront ceci.'
 </​code>​ </​code>​
  
  
python/flask/flask_login.1666981836.txt.gz · Dernière modification: 2022/10/28 18:30 par marclebrun