使用 user_loader 连接 flask-socketio

Connecting flask-socketio with user_loader

警告:很抱歉post

我们目前 运行 一个带有 couchdb 后端的烧瓶服务器。我们有几个 API 端点可以提供用户信息。我们使用 flask-login 进行用户管理。 user_loader 在每次请求时检查用户数据库:

@login_manager.user_loader
def load_user(id):
    mapping = g.couch.get('_design/authentication')
    mappingDD = ViewDefinition('_design/authentication','auth2',mapping['views']['userIDMapping']['map'])
    for row in mappingDD[id]:
        return userModel.User(row.value)

我们还有一个网段,它有一个 websocket 来启用服务器和客户端之间的聊天。下面的代码是我在看到 flask-socketio 文档的身份验证部分后采取的:

def authenticated_only(f):
    @functools.wraps(f)
    def wrapped(*args, **kwargs):
        if not current_user.is_authenticated:
            disconnect()
        else:
            return f(*args, **kwargs)
    return wrapped

我的网络套接字有以下代码:

@app.route('/sampleEndPoint/')
def chatRoom():
    return render_template('randomIndex.html', async_mode=socketio.async_mode)

@socketio.on('connect', namespace='/test')
@authenticated_only
def test_connect():
    app.logger.debug(session)
    emit('my_response', {'data': 'Connected'})

@socketio.on('disconnect_request', namespace='/test')
@authenticated_only
def disconnect_request():
    session['receive_count'] = session.get('receive_count', 0) + 1
    emit('my_response',{'data': 'Disconnected!', 'count': session['receive_count']})
    disconnect()

@socketio.on('disconnect', namespace='/test')
@authenticated_only
def test_disconnect():
    print('Client disconnected', request.sid)

其他路线一切正常。但是,当我连接到 websocket 时出现以下错误:

File "/home/sunilgopikrishna/insurance_brokerage/perilback/main.py", line 144, in load_user mapping = g.couch.get('_design/authentication') File "/home/sunilgopikrishna/.local/lib/python3.5/site-packages/werkzeug/local.py", line 343, in getattr return getattr(self._get_current_object(), name) AttributeError: '_AppCtxGlobals' object has no attribute 'couch'

我在 flask-socketio 文档中读到 login_required 不适用于 socketio。

有解决办法吗?感谢任何帮助。

此致, 加利

I read in the flask-socketio documentation that login_required does not work with socketio

当然可以,但是您没有在 socketio 事件中使用 login_required,所以这不是这里的问题。

问题是您可能有一个设置 g.couchbefore_request 处理程序。 "before" 和 "after" 处理程序只 运行 用于 HTTP 请求,它们不 运行 用于 Socket.IO,因为在这个协议中没有请求的概念,有只是一个单一的长期连接。

所以基本上,您需要找到另一种方式来访问您的用户加载程序处理程序中的数据库连接,该处理程序不依赖于 before_request 处理程序。