使用 websocket 连接时,对用户进行身份验证的可能方法是什么?
示例场景:基于 Web 的多用户聊天应用程序通过加密的 websocket 连接。如何确保(或保证)此应用程序中的每个连接都属于某个经过身份验证的用户,并且在连接期间“不能”被虚假用户模拟利用。
如果您已经在对应用程序的非 websocket 部分进行身份验证,只需在连接后将会话 cookie 作为第一条消息传递并像往常一样检查 cookie。
警告:有人指出,使用 flashsockets 时以下内容不起作用:
如果您使用的是socket.io,则更容易 - cookie 在连接时自动传递,并且可以按如下方式访问:
var io = require('socket.io');
var socket = io.listen(app);
socket.on('connection', function(client){
cookies = client.headers['cookie'];
});
SSL/TLS 可用于使用 X.509 证书对客户端和服务器进行身份验证。这取决于您使用的 Web 应用程序平台。在 apache 中,可以根据已知证书列表检查 SSL_CLIENT_CERT环境变量的有效性。这不需要使用完整的 PKI,也不需要您为每个客户购买证书。虽然我建议使用 CA 来支持服务器的 ssl 证书。
有两种方法。
一种方法是允许任何人打开 websocket 连接。让客户端在打开连接后发送一个授权令牌作为第一条消息。如果客户端在一段时间内未发送有效令牌,请关闭连接。
另一种方法是使用 cookie(它们由浏览器在每次请求时自动发送)。这需要你实现 CSRF 保护(甚至比正常情况下更多,因为 websockets 没有同源策略(SOP)。你可以在这里找到详细信息。大纲如下:
SameSite=Strict
后端在响应正文中返回一个 CSRF 令牌,并在响应标头中设置一个“websocket auth”cookieOrigin
与批准的域匹配第一种方法更简单,但缺点是它需要您有一些服务器端状态等待客户端进行身份验证。这可以允许攻击者通过消耗所有可用的套接字来执行拒绝服务攻击。