Is there a way to login a user using Flask Socket IO?

独自空忆成欢 提交于 2021-01-29 09:43:57

问题


I'm using Flask with Flask SocketIO and Flask Login.

My issue is that when I tried to use the login_user function inside of a socketio.on event, there is no error, but the user isn't logged in. My example might help illustrate this. my example event will be called for the user to login, and then /usersonly will be for after that event is called.

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

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

How do I make it so that my_func can login the user?


回答1:


Its not possible with Flask Login, because in documentation, its saying Flask Login use Cookies or Header keys for Authentication, and its not possible to access it in WebSocket(Socket IO), so i recommend to use a token based system, like in APIs, using JWT tokens.

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

Then create a decorator for login:

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

Then you can use that like this:

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

But remember, you need to pass token inside your socketio always, to make the server validation, i recommend to read this blog from Miguel Grinberh rest auth in flask



来源:https://stackoverflow.com/questions/60186473/is-there-a-way-to-login-a-user-using-flask-socket-io

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!