Есть ли способ авторизации пользователя с помощью Flask Socket IO? - PullRequest
0 голосов
/ 12 февраля 2020

Я использую Flask с Flask SocketIO и Flask Логин .

Моя проблема в том, что когда Я пытался использовать функцию login_user внутри события socketio.on, ошибки нет, но пользователь не вошел в систему. Мой пример может помочь проиллюстрировать это. my example event будет вызываться для входа пользователя в систему, а затем /usersonly будет вызываться после вызова этого события.

@socketio.on('my example event')
def my_func(json):
    ...
    login_user(user)

@app.route('/usersonly')
@login.user_required
def my_call():
    print(current_user)

Как мне сделать так, чтобы my_func мог войти в систему пользователя?

1 Ответ

1 голос
/ 12 февраля 2020

Это невозможно при Flask Входе в систему, потому что в документации говорится, что Flask Вход в систему использует Cookies или ключи заголовка для аутентификации, и его невозможно получить к нему в WebSocket (Socket IO), поэтому я рекомендую использовать Система на основе токенов, как и в API, использует токены JWT.

@socket.on('login')
def on_login(message):
    user = User.query.filter_by(email=message['email']).first()
    if not user:
       socket.emit('login', {'msg': "User not found"})

    if not user.check_password(form['password']):
       socket.emit('login', {'msg': "User not found"}) 
       return 
    user = UserSchema().dump(user).data
    token = jwt.encode(
            {'id': user['id'], 'user': user['name']})
    user['token'] = token.decode('UTF-8')
    socket.emit('login', {'user': user}) 

Затем создайте декоратор для входа в систему:

def login_required(f):
    @wraps(f)
    def decorated(message):

        try:
            data = jwt.decode(message['token'], globals.current_app.config['SECRET_KEY'])
            try:
                user = User.query.filter_by(id=data['id']).first()
                Globals.current_user = UserSchema().dump(user).data
            except Exception as e:
                return Error.api_response(Error.USER_NOT_FOUND)
        except Exception as e:

            return Error.api_response(Error.INVALID_TOKEN)
        return f(message)

    return decorated

Затем вы можете использовать это так:

@socketio.on('my example event')
@login_required
def my_func(json):
    ...

Но помните, вам нужно всегда передавать токен внутри вашей socketio, чтобы выполнить проверку сервера, я рекомендую прочитать этот блог от Мигеля Гринберха rest auth in flask

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...