2012-02-01 25 views
8

Estoy trabajando en una aplicación de matraz que necesita autenticación. He conectado el matraz de inicio de sesión pero no parece muy elegante.usando el matraz de inicio de sesión con postgresql

primer matraz de inicio de sesión tiene que asegurarse de que el usuario existe:

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

Pero también hay que utilizar 'login_user' para crear el objeto de usuario

# 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 

En el código anterior 'Usuario 'es un modelo para postgres y SignedInUser es solo un objeto que se utilizará para flask-login.

¿Alguien tiene un ejemplo de frasco de inicio de sesión utilizado con postgres?

Respuesta

35

Parece que no está entendiendo bien qué maneja Flask-Login. Está allí para realizar un seguimiento de todo lo relacionado con la sesión del usuario después de indicar que la autenticación fue exitosa (llamando al login_user). La devolución de llamada user_loader solo le dice cómo volver a cargar el objeto para un usuario que ya ha sido autenticado, como cuando alguien se vuelve a conectar una sesión de "recordarme". Los documentos no son especialmente claros en eso.

No debería haber necesidad de mantener un indicador en la base de datos para el estado de inicio de sesión del usuario. Además, el código que incluyó generará AttributeError si las credenciales son incorrectas (usuario = Ninguno).

Aquí hay un ejemplo de una aplicación Flask-SQLAlchemy. Utiliza una fuente de autenticación externa y un contenedor para el objeto de usuario SQLAlchemy, pero el proceso es básicamente el mismo.

user_loader devolución de llamada:

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

clase de usuario (contenedor para objetos 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 

sesión manejador:

@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) 

Tenga en cuenta que inicio de sesión falla si:

  • autenticación externa falla
  • consulta del usuario devuelve None (no existe el usuario)
  • login_user devuelve falso (user.is_active() == False)

Salir

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

usted necesita un @login_required para el método de cierre de sesión –

+1

Lo agregué al cierre de sesión –

+0

¿Qué tipo de cosas se incluyen en "si usuario_inicio de sesión (usuario_DB)": # hacer cosas? – Mittenchops

Cuestiones relacionadas