Websockets令牌认证使用中间件并在node.js中表达 [英] Websockets token authentication using middleware and express in node.js

查看:325
本文介绍了Websockets令牌认证使用中间件并在node.js中表达的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用node.js,express和基于以下内容的 express-ws ws

I use node.js, express and express-ws that is based on ws

Express-ws允许为websocket创建类似Express的端点.

Express-ws allows to create express-like endpoints for websockets.

我正在寻找一种基于令牌对Websocket连接中的用户进行身份验证的解决方案.由于我的ws服务器是基于HTTP服务器的

I am looking for a solution to authenticate users in websocket connections, based on a token. Since my ws server is based on an HTTP one

const wsHttpServer = http.createServer();
wsHttpServer.listen(5001);
const expressWs = require('express-ws')(app , wsHttpServer);

并且由于ws连接基于已升级为ws的HTTP连接,为什么我不能像其他路由一样在ws中传递快速路由检查的ws令牌?我的逻辑是,发送令牌,检查它,如果可以,请继续升级到ws连接.因此,我可以重用HTTP连接中使用的令牌中间件解决方案.

and since the ws connection is based on an HTTP one that gets upgraded to a ws, WHY I cannot pass a token in my ws that the express route checks, like any other one? My logic is, send the token, check it, if it is ok, proceed to upgrade to a ws connection. So, I can reuse the token-middleware solution that I have in my HTTP connections.

在节点上

我的ws服务器

const wsHttpServer = http.createServer();
wsHttpServer.listen(5001);
const expressWs = require('express-ws')(app , wsHttpServer);

//set the route

app.use('/ws', require('./routes/wsroute')); 

在该路由中,我想使用token.validate()中间件-在HTTP连接中,检查Authorization标头

In that route, I would like to use the token.validate() middleware -that in HTTP connections, checks the Authorization header

router.ws('/user/:name/:id', token.validate(),  (ws, req) => { 
    console.log('ws route data : ',vessel, req.params.name, req.params.id);
});

在我的客户中

    const socket = new WebSocket('ws://localhost',{
        path: '/user/Nick/25/',
        port: 5001, // default is 80
        protocol : "echo-protocol", // websocket protocol name (default is none)
        protocolVersion: 13, // websocket protocol version, default is 13
        keepAlive: 60,
        headers:{ some:'header', 'ultimate-question':42 } // websocket headers to be used e.g. for auth (default is none)
      });

此错误Failed to construct 'WebSocket': The subprotocol '[object Object]' is invalid

我也尝试过

const socket = new WebSocket('ws://localhost:5001/user/Nick/25', ["Authorization", localStorage.getItem('quad_token')]);

我没有收到任何错误,但是我不知道如何在节点中获取Authorization"header"

I dont get any errors, but I dont know how to get the Authorization "header" in node

我可以

只需向const socket = new WebSocket(currentUrl);发送一些数据,然后在该数据中包含有效令牌即可.但是要检查它,我必须先允许连接.我不想,我想使用一种中间件解决方案,该解决方案可以自动检查令牌并允许或不允许继续.

just send const socket = new WebSocket(currentUrl); with some data and include a valid token in that data. But to check it, I have to allow the connection first. I dont want that, I would like to use a middleware solution that automatically checks a token and allows or not to continue.

问题

请帮助我了解:

1是否可以在ws中使用基于令牌的,基于中间件的解决方案?

1 Is it possible to use a token-based, middleware-based solution in ws?

2如何在ws连接中设置带有令牌的标头?

2 How to set a header with a token in a ws connection?

3如何在节点中获取该令牌?

3 How to get that token in node?

推荐答案

1)根据我的经验,没有可用的express.js中间件,我发现的解决方案要求监听您HTTP服务器上的升级事件并阻止对您的套接字连接到达ws路由之前.

1) In my experience there is no available express.js middleware and the solution i found requires to listen to the upgrade event on your http server and blocking access to your socket connection before it reaches ws routes.

2)您的浏览器将不允许在客户端的Websocket连接期间设置其他标头.它会通过cookie发送,因此您可以利用express-session来首先在服务器上授权用户,然后在浏览器中设置cookie,并在websocket连接期间发送该cookie.

2) Your browser will not allow setting additional headers during websocket connection on the client side. It will send though the cookies so you can make use of express-session to authorize on your server first the user, a cookie will be set on the browser and that cookie will be sent over during the websocket connection.

3)您可以在此答案中做到拦截(并且可能拒绝)Web套接字升级请求从此处复制代码以供您自己仔细阅读.

3) You can do like in this answer Intercept (and potentially deny) web socket upgrade request Copying the code here from there for your own perusal.

**wsHttpServer**.on('upgrade', function (req, socket, head) {
      var validationResult = validateCookie(req.headers.cookie);
      if (validationResult) {
        //...
      } else {
        socket.write('HTTP/1.1 401 Web Socket Protocol Handshake\r\n' +
                     'Upgrade: WebSocket\r\n' +
                     'Connection: Upgrade\r\n' +
                     '\r\n');
                     socket.close();
                     socket.destroy();
                     return;
      }
      //...
    });

这篇关于Websockets令牌认证使用中间件并在node.js中表达的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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