используя флеш-логин с postgresql - PullRequest
9 голосов
/ 01 февраля 2012

Я работаю над приложением для колб, которое требует аутентификации. Я подключил флеш-логин, но он не выглядит изящным.

При первом входе в систему необходимо убедиться, что пользователь существует:

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

Но вам также необходимо использовать 'login_user' для создания объекта пользователя

# 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

В приведенном выше коде «Пользователь» - это модель для postgres, а SignedInUser - просто объект, который будет использоваться для входа в флеш-память.

У кого-нибудь есть пример входа в систему с помощью postgres?

1 Ответ

38 голосов
/ 08 февраля 2012

Похоже, вы неправильно понимаете, что обрабатывает Flask-Login.Он предназначен для отслеживания всего, что связано с сеансом пользователя, после того, как вы скажете, что аутентификация прошла успешно (путем вызова login_user.) Обратный вызов user_loader говорит только о том, как перезагрузить объект для пользователя, который уже был аутентифицирован, например,когда кто-то подключается к сеансу «помни меня».Документы не совсем ясны по этому поводу.

Не должно быть необходимости хранить флаг в базе данных для статуса входа пользователя.Кроме того, код, который вы включили, вызовет AttributeError, если учетные данные неверны (user = None).

Вот пример из приложения Flask-SQLAlchemy.Он использует внешний источник аутентификации и оболочку для объекта «Пользователь SQLAlchemy», но процесс в основном такой же.

обратный вызов 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

Класс пользователя (оболочка для объекта 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

Обработчик входа в систему:

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

Обратите внимание, что вход в систему завершится неудачно, если:

  • внешняя аутентификация не пройдена
  • запрос пользователя возвращает None (пользователь не существует)
  • login_user возвращает значение False (user.is_active() == False)

Выход из системы

@app.route('/logout')
@login_required
def logout():
    logout_user()
    flash('You have logged out')
    return(redirect(url_for('login')))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...