不幸的是,对于 websocket 连接,大多数2 个websocket 客户端和服务器不支持附加标头和自定义标头1 。所以可能的选择是:
缺点:它可能很容易受到攻击,因为它可能最终出现在日志和系统进程信息中,可供有权访问服务器的其他人使用,更多信息请点击此处
解决方案:加密令牌并附加它,因此即使可以在日志中看到它,在解密之前它也没有任何用处。
客户端:
# Append jwt to protocols
new WebSocket(url, existing_protocols.concat(jwt))
我为它创建了一个 JS 库action-cable-react-jwt,React
它React-Native
就是这样做的。随意使用它。
服务器端:
# get the user by
# self.current_user = find_verified_user
def find_verified_user
begin
header_array = self.request.headers[:HTTP_SEC_WEBSOCKET_PROTOCOL].split(',')
token = header_array[header_array.length-1]
decoded_token = JWT.decode token, Rails.application.secrets.secret_key_base, true, { :algorithm => 'HS256' }
if (current_user = User.find((decoded_token[0])['sub']))
current_user
else
reject_unauthorized_connection
end
rescue
reject_unauthorized_connection
end
end
1大多数 Websocket API(包括Mozilla 的)就像下面这样:
WebSocket 构造函数接受一个必需参数和一个可选参数:
WebSocket WebSocket(
in DOMString url,
in optional DOMString protocols
);
WebSocket WebSocket(
in DOMString url,
in optional DOMString[] protocols
);
url
要连接的 URL;这应该是 WebSocket 服务器将响应的 URL。
protocols
选修的
单个协议字符串或协议字符串数组。这些字符串用于指示子协议,以便单个服务器可以实现多个 WebSocket 子协议(例如,您可能希望一个服务器能够根据指定的协议处理不同类型的交互)。如果您未指定协议字符串,则假定为空字符串。
2总是有例外,例如,这个 node.js lib ws允许构建自定义标头,因此您可以使用通常的Authorization: Bearer token
标头,并在服务器上解析它,但客户端和服务器都应该使用ws
.