Javascript websocket客户端库,可以在握手请求中传递自定义标头 [英] Javascript websocket client library which can pass custom headers in handshake request

查看:1524
本文介绍了Javascript websocket客户端库,可以在握手请求中传递自定义标头的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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 ?

推荐答案

我很遗憾成为坏消息的承载者......但是 - 如问题,您可以从标准的Websocket API (这不是外部库,它是随附的浏览器)...你不能为websocket连接设置自定义标题。

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 comes with the browser)... you cannot set custom headers for websocket connections.


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

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.

因为这个是你的websocket服务器,你有选择:

Since this is YOUR websocket server, you have options:


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

  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.com/?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:

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

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....

所以,有可能设置一个唯一的cookie - 或者,甚至更好(假设您的http和websocket共享相同的代码库并一起工作),在服务器端会话存储中设置身份验证令牌 - 并使用该数据来验证连接或拒绝它。

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.

由于我不是Python专家,这里是使用Ruby的快速演示 Plezi框架(我是作者):

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

访问: http:// loaclhost:3000 /

to尝试启动websocket,打开Web检查器并在控制台中运行以下脚本:

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

这应该是FAIL,因为我们还没有验证...

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

访问 http:// loaclhost:3000 / login 并重试。

现在它应该可以工作。

尝试 http:// loaclhost:3000 / logout 如果你愿意的话。

这篇关于Javascript websocket客户端库,可以在握手请求中传递自定义标头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆