问题
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