[英][Express][Nodejs] How to decrypt express-session cookie during socket.io connection?
[英]express-session isn't setting session cookie while using with socket.io
我正在嘗試使用 socket.io 實現身份驗證和會話。
經過大量研究1 ,我設置了以下使用 express 和 express-session 的方法。
問題是,express 和 socket.io 連接似乎有不同的會話,因為我得到的id
不同。
此外,我的應用程序的瀏覽器中沒有設置 cookie(這可能是兩個組件創建不同會話的原因?)
我正在使用 express 4.13.3
express-session 1.12.1
和 socket.io 1.3.7
。
下面是我設置的服務器端代碼:
var app = require('express')();
var server = app.listen(80);
var parser = require('body-parser');
var Session = require('express-session');
var io = require('socket.io')(server);
var game = require('./game.js');
var session = Session({
secret: 'some secret',
resave: false,
saveUninitialized: false,
cookie: {
'name': 'test',
httpOnly: false,
secure: false,
maxAge: ((60 * 1000) * 60)
}
});
app.use(parser.urlencoded({
extended: false
}));
app.use(session);
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
app.post('/login', function(req, res) {
console.log('login %s', req.session.id);
console.dir(req.session, {
color: true
});
res.json({
status: 'success'
});
});
io.use(function(socket, next) {
session(socket.handshake, {}, next);
});
console.log('socket server started @ %s !', 80);
io.on('connection', function(socket) {
console.log('user connected %s', socket.handshake.session.id);
console.dir(socket.handshake.session, {
color: true
});
socket.on('disconnect', function() {
console.log('user disconnected');
console.dir(socket.handshake.session, {
color: true
});
});
});
以及客戶端用於測試目的的代碼:
$.ajax({
url: 'http://127.0.0.1:80/login',
type:'post',
success: function(response) {
var socket = io('http://127.0.0.1:80');
}
});
以下是控制台中的輸出:
這是瀏覽器中的資源部分:
我什至很困惑看到session
對象在登錄控制台時沒有任何id
屬性,但是session.id
打印了不同的值。 也許這來自對象原型鏈或其他東西。
我能想到的與我的代碼和教程的唯一區別是,它們都從同一個快速服務器提供index.html
頁面。 就我而言,我在本地擁有該文件。
我在某處讀到過,在這種情況下,我必須在建立 socket.io 連接之前發送一個http
請求來表達。
socket.io.js
客戶端庫由 express 和 socket.io ( <script src="http://127.0.0.1/socket.io/socket.io.js"></script>
),除此之外,在建立套接字連接之前,我還會使用快速路由/login
進行測試。
所以我想知道為什么沒有在客戶端設置 cookie,以及為什么 express 和 socket 請求創建了不同的會話......? 我在這里錯過了什么..?
1代碼主要基於:
PS:我想做的是,當套接字客戶端重新連接時,我需要將他放回會話詳細信息所在的位置。 我真的不想與 express 共享會話,但是 express 中間件是我遇到的使用 socket.io 實現會話的唯一方法。
問題與 express 或 socket.io 無關。 問題是,我從 express 和 socket.io 服務器以外的本地服務器加載項目。
所以這是一個跨域ajax請求,在這種情況下一些瀏覽器拒絕處理Set-Cookie
頭。 我們可以通過在此答案中提到的 ajax 選項中添加以下內容來解決此問題:
xhrFields: {
withCredentials: true
},
或者,如果您正在使用 angular,發送{withCredentials: true}
就像
$http({withCredentials: true, ...}).get(...)
如本答案所述。
在服務器端,設置此標頭:
res.header("Access-Control-Allow-Credentials", 'true');
如果添加,chrome 將不再允許您在Access-Control-Allow-Origin
標頭中使用通配符*
。 您還應該將其設置為特定的允許域。
res.header("Access-Control-Allow-Origin", "allowed domains");
你不應該
res.session.save(); // add this line
res.json({ status: 'success' }); // or just res.send({status:success});
?
而且,我建議您為此目的使用帶有passport-local
策略的passport
模塊,這樣您就不必擔心為什么您的會話不起作用。 有一次它為我節省了很多時間。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.