使用 socket.io 解析 cookie

Posted

技术标签:

【中文标题】使用 socket.io 解析 cookie【英文标题】:Parsing cookies with socket.io 【发布时间】:2017-01-09 08:42:43 【问题描述】:

我正在尝试正确读取节点服务器上由我通过 localhost:3000 上的浏览​​器控制台设置的 cookie,如下所示:

document.cookie = "tagname = test;secure";
document.cookie = "hello=1"

在我的节点服务器中,我使用 sockets.io,当我收到连接请求时,我可以访问如下所示的属性:

socket.request.headers.cookie   

这是一个字符串,我总是这样看:

'io=QhsIVwS0zIGd-OliAAAA' //what comes after io= is random.

我尝试用各种模块翻译它,但它们似乎无法解析字符串。这是我最近的尝试:

var cookie = require('cookie');

io.sockets.on('connection', function(socket)  
    socket.on('addUser', function()
        var a = socket.request.headers.cookie;
        var b = cookie.parse(a); //does not translate
        console.log(b);
    );
       

我显然想获得一个对象,其中包含浏览器上每个 io.connect 发送的所有 cookie。 我一直在尝试解决它 5 个小时,我真的不知道我在这里做错了什么。

【问题讨论】:

客户是什么?我没有定义任何所谓的“客户”。当我粘贴该行时,我得到“未定义客户端” 对不起,请忽略 @user1938653 您也可以在 URL 中将对象从客户端发送到服务器(io.connect('localhost:3000?key:value')),在后端,您可以从 URL 中获取对象套接字中间件。 @KlwntSingh 不是一个好主意,因为每次要更改 URL 参数的值时都必须重新建立 Socket 连接。 【参考方案1】:

尝试使用 socket.handshake 代替 socket.request

【讨论】:

刚刚做了,我看到的东西格式相同,意思是一样的。 有人能解释一下为什么要使用socket.handshake vs socket.request吗?【参考方案2】:

使用Cookie 模块。这正是您正在寻找的。​​p>

var cookie = require('cookie');

cookie.parse(str, 选项) 解析 HTTP Cookie 标头字符串并返回所有 cookie 名称-值对的对象。 str 参数是表示 Cookie 标头值的字符串,options 是包含附加解析选项的可选对象。

var cookies = cookie.parse('foo=bar; equation=E%3Dmc%5E2');
//  foo: 'bar', equation: 'E=mc^2'  

希望对你有帮助

【讨论】:

【参考方案3】:

没有正则表达式

//Get property directly without parsing
function getCookie(cookie, name)
    cookie = ";"+cookie;
    cookie = cookie.split("; ").join(";");
    cookie = cookie.split(" =").join("=");
    cookie = cookie.split(";"+name+"=");
    if(cookie.length<2)
        return null;
    
    else
        return decodeURIComponent(cookie[1].split(";")[0]);
    

//getCookie('foo=bar; equation=E%3Dmc%5E2', 'equation');
//Return : "E=mc^2"

或者如果你想将cookie解析为对象

//Convert cookie string to object
function parseCookie(cookie)
    cookie = cookie.split("; ").join(";");
    cookie = cookie.split(" =").join("=");
    cookie = cookie.split(";");

    var object = ;
    for(var i=0; i<cookie.length; i++)
        cookie[i] = cookie[i].split('=');
        object[cookie[i][0]] = decodeURIComponent(cookie[i][1]);
    
    return object;


//parseCookie('tagname = test;secure');
//Return : tagname: " test", secure: "undefined"

【讨论】:

【参考方案4】:

IO cookie 是 socket.io 用作用户 ID 的默认 cookie。你可以设置它,但如果你不这样做,它会创建一个并为其设置一个哈希值。 Read about the option here.

我认为这不是代码问题。这是您的代码示例。当我添加 cookie 测试并将其设置为 1

var app = require('express')();
var http = require('http').Server(app);
var cookie = require('cookie')
var io = require('socket.io')(http);
var port = process.env.PORT || 3000;

app.get('/', function(req, res)
  res.sendFile(__dirname + '/index.html');
);

io.sockets.on('connection', function(socket) 
    socket.on('chat message', function()
        var a = socket.request.headers.cookie;
        var b = cookie.parse(a); //does not translate
        console.log(b);
    );
);

http.listen(port, function()
  console.log('listening on *:' + port);
);

服务器输出

 io: 'TxvLfvIupubZpOaGAAAF', test: '1' 

如果我把它改成这个。

var io = require('socket.io')(http, 
  cookie : 'id'
);

输出会将其更改为。

 id: 'ZJPSwFsQAje0SrgsAAAD', test: '1' 

【讨论】:

以上是关于使用 socket.io 解析 cookie的主要内容,如果未能解决你的问题,请参考以下文章

需要使用 Socket io 解析 live json 文件

socket.io-client-swift 包解析在 Xcode13 Beta 项目中失败

通过io.sockets.sockets解析时如何获取socket id

socket.io官方实例聊天室的源码解析

对象内的 Socket.io 客户端

如何对使用 cookie 的 socket.io 中间件进行单元测试