繁体   English   中英

使用自己的凭据的Websocket安全身份验证

[英]Websocket security authentication with own credentials

我需要一种方法来保护我的WebSockets。

类似于onConnect->checkcredentials if(credentials===false){die()}

但是带有自己的凭据数据发送到服务器。 我怎么能没有令牌或cookie? 如果没有,是否还有其他解决方案可以安全地进行实时通信?

我需要一种方法来保护我的WebSockets。

解决方案:套接字握手查询

使用此方法,只有知道参数和机密的客户端才能通过握手网关(中间件)

[编辑:使用新的socket.io 2.0它已解决有关查询的问题 ]

@ 客户

io('http://216.157.91.131:8080/', { query: "s=$€CR€T" });

@ 服务器

var theSecret = "S€CR€T";
io.use(function(socket, next) {
  var handshakeSecret = socket.request._query['s'];
  console.log("middleware:", handshakeSecret);
  try{
   if(handshakeSecret=theSecret){next();}else{socket.disconnect();}
  }catch(e){socket.disconnect();} //prevent error - crash
});

在这种情况下, theSecret对于所有人theSecret都是相同的,可以是数据库中的特定检查。

解决方案:Auth或GTFO! (踢)

如果客户端在超时内未提供正确的凭据,也可以使连接到断开连接的客户端(计时器踢)失败。 范例:

const SOCKET_AUTH_TIMEOUT = 120000; //2 minutes in ms
io.on('connection', function(socket){
    //.: ALL SOCKET CONNECTIONS :.
    console.log("[+] (unauthorized) client connected : "+socket.id);
     //begin doom countdown...
    socket.doom = setTimeout(KickSocketClient.bind(null, socket.id), SOCKET_AUTH_TIMEOUT);
     //warn this client : (example)
     //@ client : 'You got '+TimeoutInMinutes+' minutes to authorize before being kicked.'
    socket.emit('auth_required', SOCKET_AUTH_TIMEOUT);
    //.: Handle Authorization :.
    socket.on('auth',function(authRequest){
     /* your logic to verify the incoming authRequest goes here, for example :*/
     if(DATABASE[authRequest.user]){ //user exists in imaginary in-memory database
      if(DATABASE[authRequest.user].password == authRequest.password){ //correct password, success!
        socket.emit('authed', DATABASE[authRequest.user]); //maybe return user data
        socket.authed = true; //set this socket client as authorized (useful for future requests)
        //now clear the timeout of d00m! (prevent the disconnection, now the client is authed)
        clearTimeout(socket.doom);
      }else{socket.emit('error','credentials');}
     }else{socket.emit('error','credentials');}
    });
    //.: Handle Disconnections :.
    socket.on('disconnect', function(){
     if(socket.authed){console.log("[+] client disconnected : "+socket.id);}
     else{console.log("[+] (unauthorized) client disconnected : "+socket.id);}
    });
    //.: Only for Authorized Clients :.
    socket.on('secret', function(){
     if(socket.authed){
        console.log("[o] client : "+socket.id+" requested the secret");
        socket.emit('return','the secret to life'); //here you go!
     }else{socket.disconnect();} // disconnect the unauthorized client
    });
});

function KickSocketClient(sid){
 if (io.sockets.connected[sid]) {
    console.log("[kick] client ("+sid+") : unauthorized status for too long"); 
    io.sockets.connected[sid].disconnect();
 }else{ console.log("<!> : [kick] client ("+sid+") not found!"); }
}

如果客户端未在SOCKET_AUTH_TIMEOUT指定的时间内进行身份验证 ,则它将断开连接。

在示例中,我还提供了一个仅授权客户端的小演示(未认证时的请求=断开连接)

您还可以使它们在通过身份验证后加入特定的专用命名空间,以便向所有客户端进行的全局广播不包括未经身份验证的侦听器。

祝您好运,希望对您有所帮助。

注意 :

还有其他解决方案可以安全地进行实时通信吗?

要回答这个问题,您需要首先考虑一下威胁。 有多种安全保护方法,例如,通过SSL使用socket.io。

我提到的解决方案是为了避免未授权的客户端保持在线状态并访问事件/资源/等...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM