使用user_loader连接flask-socketio

时间:2017-02-27 04:51:30

标签: flask flask-login flask-socketio

警告:对长篇文章道歉

我们目前正在运行带有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时出现以下错误:

  

档案“/home/sunilgopikrishna/insurance_brokerage/perilback/main.py”,   第144行,在load_user中       mapping = g.couch.get('_ design / authentication')File“/home/sunilgopikrishna/.local/lib/python3.5/site-packages/werkzeug/local.py”,   第343行,在 getattr 中       return getattr(self._get_current_object(),name)AttributeError:'_ AppCtxGlobals'对象没有属性'couch'

我在flask-socketio文档中读到了login_required不能与socketio一起使用。

有解决方法吗?任何帮助表示赞赏。

此致 Galeej

1 个答案:

答案 0 :(得分:1)

  

我在flask-socketio文档中读到login_required不能与socketio一起使用

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

问题是你可能有一个设置before_request的{​​{1}}处理程序。 “之前”和“之后”处理程序仅针对HTTP请求运行,它们不运行Socket.IO,因为在此协议中没有请求的概念,只有一个长期连接。

基本上,您需要找到另一种方法来访问不依赖g.couch处理程序的用户加载程序处理程序中的数据库连接。