using flask-login with postgresql

后端 未结 1 1340
生来不讨喜
生来不讨喜 2021-01-30 12:06

I\'m working on a flask app that needs authentication. I\'ve hooked up flask-login but it doesn\'t seem very graceful.

First flask-login needs to make sure the user exis

1条回答
  •  再見小時候
    2021-01-30 12:53

    It looks like you might be misunderstanding what Flask-Login handles. It's there to keep track of everything about the user's session after you tell it authentication was successful (by calling login_user.) The user_loader callback only tells it how to reload the object for a user that has already been authenticated, such as when someone reconnects to a "remember me" session. The docs are not especially clear on that.

    There should be no need to keep a flag in the database for the user's login status. Also, the code you included will raise an AttributeError if the credentials are incorrect (user = None).

    Here's an example from a Flask-SQLAlchemy application. It uses an external authentication source and a wrapper for the SQLAlchemy User object, but the process is basically the same.

    user_loader callback:

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

    User class (wrapper for SQLAlchemy object):

    # 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
    

    Login handler:

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

    Note that login fails if:

    • external auth fails
    • user query returns None (user does not exist)
    • login_user returns False (user.is_active() == False)

    Logout

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

    0 讨论(0)
提交回复
热议问题