我需要一个javascript库连接到我的web-socket服务器,这是使用python twisted实现的。我尝试了原生javascript web-socket客户端,但它没有传递自定义标头 as per this link的选项。我的Web套接字服务器通过从Oauth2标准中的握手头中获取auth_token来进行身份验证。是否有任何javascript库可用于Web套接字客户端,允许在连接时传递自定义标头?
答案 0 :(得分:6)
我很抱歉成为坏消息的承担者......但是 - 正如the question中提及的那样,您正在引用the standard Websocket API,这可以从Plezi framework中学习(这不是'一个外部库,它是浏览器附带的内容)...你不能为websocket连接设置自定义标题。
WebSocket(url,protocols)构造函数接受一个或两个参数。第一个参数url指定要连接的URL。第二种协议(如果存在)是字符串或字符串数组。 ...数组中的每个字符串都是一个子协议名称。仅当服务器报告已选择其中一个子协议时才建立连接。 ...
但是,一切都没有丢失。
由于这是您的websocket服务器,您可以选择:
我非常确定OAuth2使用令牌作为GET或POST请求的参数,而不是自定义标头。这意味着(可能)您可以将令牌作为连接字符串的一部分传递,即:
websocket = new WebSocket('wss://my.server.com/?access_token=secret_acess_token');
如此传递会话令牌可能并不理想,可能会带来安全风险 ......所以我会选择第二个选项:
新的websocket连接(除非我的浏览器是特殊的)使用与建立主连接相同的cookie启动 - 这意味着来自Http层的所有cookie和会话数据都可以被websocket层访问。 ...
因此,可以设置一个唯一的cookie - 或者更好(假设你的http和websocket共享相同的代码库并且可以很好地协同工作),在服务器端会话存储中设置一个身份验证令牌 - 和使用该数据来验证连接或拒绝连接。
由于我不是Python专家,所以这里是使用Ruby http://loaclhost:3000/(我是作者)的快速演示:
require 'plezi'
class DemoCtrl
# this is the Http index page response
def index
response.write "#{cookies[:notice]}\n\n" if cookies[:notice] && (cookies[:notice] = nil).nil?
#returning a string automatically appends it to the response.
"We have cookies where we can place data:\n#{request.cookies.to_s}\n"
end
# the login page
def login
cookies[:my_token] = "a secret token"
cookies[:notice] = "logged in"
redirect_to :index
end
# the logout page
def logout
cookies[:my_token] = nil
cookies[:notice] = "logged out"
redirect_to :index
end
# a Plezi callback, called before a websocket connection is accepted.
# it's great place for authentication.
def pre_connect
puts "Websocket connections gave us cookies where we can place data:\n#{request.cookies.to_s}\n"
return false unless cookies.to_s[:my_token] == "a secret token"
# returning true allows the connection to be established
true
end
def on_message data
puts "echoing #{data}"
response << "echo: #{data}"
end
end
# setup the route to our demo
Plezi.route '/', DemoCtrl
# Plezi will start once the script is finished.
# if you are running this in irb, use:
exit
访问:http://loaclhost:3000/login
尝试启动websocket,打开Web检查器并在控制台中运行以下脚本:
ws = new WebSocket("ws://localhost:3000/"); ws.onopen = function(e) { console.log("open"); }; ws.onmessage = function(e) { console.log(e.data);};
ws.send("Go Bears");
这应该失败,因为我们还没有认证......
访问http://loaclhost:3000/logout然后重试。
现在应该可以了。
如果您愿意,请尝试{{3}}。