Javascript websocket客户端库,可以在握手请求中传递自定义标头

时间:2015-10-26 05:15:13

标签: javascript websocket

我需要一个javascript库连接到我的web-socket服务器,这是使用python twisted实现的。我尝试了原生javascript web-socket客户端,但它没有传递自定义标头 as per this link的选项。我的Web套接字服务器通过从Oauth2标准中的握手头中获取auth_token来进行身份验证。是否有任何javascript库可用于Web套接字客户端,允许在连接时传递自定义标头?

1 个答案:

答案 0 :(得分:6)

我很抱歉成为坏消息的承担者......但是 - 正如the question中提及的那样,您正在引用the standard Websocket API,这可以从Plezi framework中学习(这不是'一个外部库,它是浏览器附带的内容)...你不能为websocket连接设置自定义标题。

  

WebSocket(url,protocols)构造函数接受一个或两个参数。第一个参数url指定要连接的URL。第二种协议(如果存在)是字符串或字符串数​​组。 ...数组中的每个字符串都是一个子协议名称。仅当服务器报告已选择其中一个子协议时才建立连接。 ...

但是,一切都没有丢失。

由于这是您的websocket服务器,您可以选择:

  1. 我非常确定OAuth2使用令牌作为GET或POST请求的参数,而不是自定义标头。这意味着(可能)您可以将令牌作为连接字符串的一部分传递,即:

     websocket = new WebSocket('wss://my.server.com/?access_token=secret_acess_token');
    

    如此传递会话令牌可能并不理想,可能会带来安全风险 ......所以我会选择第二个选项:

  2. 新的websocket连接(除非我的浏览器是特殊的)使用与建立主连接相同的cookie启动 - 这意味着来自Http层的所有cookie和会话数据都可以被websocket层访问。 ...

    因此,可以设置一个唯一的cookie - 或者更好(假设你的http和websocket共享相同的代码库并且可以很好地协同工作),在服务器端会话存储中设置一个身份验证令牌 - 和使用该数据来验证连接或拒绝连接。

  3. 由于我不是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}}。