admin管理员组

文章数量:1355731

I need a javascript library to connect to my web-socket server which is implemented using python twisted. I tried Native javascript web-socket client but it doesn’t have the option to pass custom headers as per this link. My web-socket server does authentication by taking auth_token from handshake header as in Oauth2 standard. Is there any javascript library available for web-socket clients which allows to pass custom header while connecting ?

I need a javascript library to connect to my web-socket server which is implemented using python twisted. I tried Native javascript web-socket client but it doesn’t have the option to pass custom headers as per this link. My web-socket server does authentication by taking auth_token from handshake header as in Oauth2 standard. Is there any javascript library available for web-socket clients which allows to pass custom header while connecting ?

Share Improve this question edited May 23, 2017 at 12:10 CommunityBot 11 silver badge asked Oct 26, 2015 at 5:15 Bill GoldbergBill Goldberg 1,8295 gold badges30 silver badges52 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 6

I'm sorry to be the bearer of bad news... but - as mentioned both in the question you are referencing and as you can learn from the standard Websocket API (this isn't an external library, it's what es with the browser)... you cannot set custom headers for websocket connections.

The WebSocket(url, protocols) constructor takes one or two arguments. The first argument, url, specifies the URL to which to connect. The second, protocols, if present, is either a string or an array of strings. ... Each string in the array is a subprotocol name. The connection will only be established if the server reports that it has selected one of these subprotocols. ...

But, all is not lost.

Since this is YOUR websocket server, you have options:

  1. I'm pretty sure that OAuth2 uses the token as a parameter for a GET or POST request and NOT as a custom header. This means that (maybe) you can pass the token as part of the connection string, i.e.:

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

    Passing the session token like so might not be ideal and could pose a security risk... so I would go with the second options here:

  2. New websocket connections (unless my browsers are special) are initiated with the same cookies that the main connection was established with - this means that all the cookies and session data from the Http layer is accessible to the websocket layer....

    So, It's possible to set a unique cookie - or, even better (assuming your http and websocket share the same codebase and work well together), set an authentication token within a server-side session storage - and use that data to authenticate a connection or to refuse it.

Since I'm no Python expert, here's a quick demo using Ruby's Plezi framework (I'm the author):

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

visit: http://loaclhost:3000/

to try and initiate a websocket, open up the web inspector and run the following script in the console:

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");

This should FAIL, because we didn't authenticate yet...

visit http://loaclhost:3000/login and try again.

Now it should work.

Try http://loaclhost:3000/logout if you feel like it.

本文标签: Javascript websocket client library which can pass custom headers in handshake requestStack Overflow