Отключить одновременный вход из нескольких разных мест на Flask-Login

У меня есть веб-служба, написанная на Flask. Пользователь A использует некоторое имя пользователя для входа в службу. Я хочу, чтобы пользователь B не мог войти в систему, используя то же имя пользователя, пока не истечет срок действия сеанса пользователя A. Другими словами, я хочу отключить одновременный одновременный вход в систему для каждого пользователя. Как мне это сделать в Flask-Login?


person Mirzhan Irkegulov    schedule 29.04.2014    source источник
comment
Когда пользователь A входит в систему, сохраните эту информацию на стороне сервера (база данных, файл и т. д.), а затем всегда проверяйте эту информацию на стороне сервера перед входом в систему, если пользователь уже вошел в систему.   -  person codegeek    schedule 29.04.2014
comment
Знаете ли вы какие-либо примеры того, где это реализовано? Я понял идею, но я хочу убедиться, что я могу сделать это правильно   -  person themantalope    schedule 05.12.2016
comment
Кто-нибудь смог в этом разобраться?   -  person kiran.koduru    schedule 03.03.2017


Ответы (1)


Что вам нужно сделать, так это сохранить какой-то токен сеанса в вашей модели пользователя в базе данных.

class User(db.Model):
    ....
    session_token = db.Column(db.String(40), index=True) 

Когда пользователь входит в систему, вы создаете токен сеанса и сохраняете его в базе данных.

Обновите функцию User.get_id, чтобы она возвращала токен сеанса вместо идентификатора пользователя.

def get_id(self):                                                           
    return str(self.session_token) 

В обратном вызове user_loader вы ищете пользователя на основе токена:

@lm.user_loader                                                                 
def load_user(session_token):                                                                                                                        
    return User.query.filter_by(session_token=session_token).first()

При такой настройке токен будет обновляться при каждом входе в систему, что автоматически делает предыдущие сеансы недействительными.

Документация

person Matt Healy    schedule 12.04.2017
comment
Спасибо, это работает. Есть ли способ разрешить одновременный вход максимум для 2 устройств? - person stenlytw; 28.06.2019
comment
Я пытался сгенерировать и сохранить токен сеанса сразу после вызова login_user(), но get_id() вызывается до того, как токен сеанса может быть установлен. Я хочу установить токен сеанса после возврата login_user(), чтобы я мог гарантировать, что процесс входа в систему работал нормально. - person Filipe Bezerra de Sousa; 21.06.2020
comment
Я использовал сигналы Flask для захвата, когда пользователь входит в систему для сохранения токена сеанса, сгенерированного с помощью secrets.token_urlsafe(). - person Filipe Bezerra de Sousa; 21.06.2020
comment
Но уведомление происходит после вызова get_id(). Единственный способ, которым я нашел, чтобы это работало, - это вручную создать и сохранить токен сеанса в базе данных перед вызовом login_user(), но таким образом приложение может вести себя непоследовательно. - person Filipe Bezerra de Sousa; 21.06.2020