2012-02-01 4 views
8

Je travaille sur une application flask qui nécessite une authentification. J'ai connecté un flask-login mais ça ne semble pas très gracieux.en utilisant flask-login avec postgresql

premier flacon-connexion doit assurer que l'utilisateur existe:

@login_manager.user_loader 
def load_user(id): 
    return User.query.get(id) 

Mais vous devez également utiliser « login_user » pour créer l'objet utilisateur

# Some code above 
    user = User.query.filter_by(email = form.email.data, password = form.password.data).first() 
    user.login_status = 1 
    db.session.commit() 
    login_user(objects.SignedInUser(user.id, user.email, user.login_status == LoginStatus.Active))  
# Some code below 

Dans le code ci-dessus « utilisateur 'est un modèle pour postgres et SignedInUser est juste un objet à utiliser pour flask-login.

Quelqu'un at-il un exemple de connexion flask utilisé avec postgres?

Répondre

35

Il semble que vous ne compreniez peut-être pas ce que Flask-Login gère. Il est là pour garder une trace de tout sur la session de l'utilisateur après que vous lui avez dit que l'authentification a réussi (en appelant login_user). Le rappel user_loader indique seulement comment recharger l'objet pour un utilisateur qui a déjà été authentifié, comme lorsque quelqu'un se reconnecte à une session "souvenez-vous de moi". Les docs ne sont pas particulièrement claires à ce sujet.

Il ne devrait pas être nécessaire de conserver un indicateur dans la base de données pour l'état de connexion de l'utilisateur. En outre, le code que vous avez inclus déclenchera une AttributeError si les informations d'identification sont incorrectes (user = None).

Voici un exemple d'une application Flask-SQLAlchemy. Il utilise une source d'authentification externe et un wrapper pour l'objet SQLAlchemy User, mais le processus est fondamentalement le même.

rappel user_loader:

@login_manager.user_loader 
def load_user(user_id): 
    user = User.query.get(user_id) 
    if user: 
     return DbUser(user) 
    else: 
     return None 

classe utilisateur (emballage pour objet SQLAlchemy):

# User class 
class DbUser(object): 
    """Wraps User object for Flask-Login""" 
    def __init__(self, user): 
     self._user = user 

    def get_id(self): 
     return unicode(self._user.id) 

    def is_active(self): 
     return self._user.enabled 

    def is_anonymous(self): 
     return False 

    def is_authenticated(self): 
     return True 

Connexion gestionnaire:

@app.route('/login', methods=['GET', 'POST']) 
def login(): 
    error = None 
    next = request.args.get('next') 
    if request.method == 'POST': 
     username = request.form['username'] 
     password = request.form['password'] 


     if authenticate(app.config['AUTH_SERVER'], username, password): 
      user = User.query.filter_by(username=username).first() 
      if user: 
       if login_user(DbUser(user)): 
        # do stuff 
        flash("You have logged in") 

        return redirect(next or url_for('index', error=error)) 
     error = "Login failed" 
    return render_template('login.html', login=True, next=next, error=error) 

Notez que la connexion échoue si:

  • auth externe échoue
  • requête de l'utilisateur retourne Aucun (utilisateur n'existe pas)
  • login_user retourne false (user.is_active() == False)

Déconnexion

@app.route('/logout') 
@login_required 
def logout(): 
    logout_user() 
    flash('You have logged out') 
    return(redirect(url_for('login'))) 
+1

vous avez besoin d'une @login_required pour la méthode logout –

+1

je l'ai ajouté à la déconnexion –

+0

Quel genre de choses tombe sous "si login_user (DbUser (utilisateur)): # faire des choses"? – Mittenchops

Questions connexes