2015-02-18 1 views
1

У меня есть простое приложение express, в котором используется промежуточное ПО session вместе с промежуточным программным обеспечением passport-local. Затем я использую share.js с browserchannel для передачи данных на сервер через share.listen (поток). Все в соответствии с документацией here.Force share.js использует те же данные экспресс-сессии

Моя проблема заключается в том, что я не могу получить доступ к данным сеанса (измененным паспорт-локальным и содержащим идентификатор пользователя, который был зарегистрирован) в потоке. Мне нужно, чтобы он мог ограничивать/предоставлять доступ в пределах client.on ('message', function (data) {..});, основанный на некоторой логике, но в первую очередь необходимо проверить, что сообщение произошло от пользователя. Там, если я попытаюсь прочитать идентификатор, он будет отличаться от того, что potencialy находится внутри req.user._id. Кажется, что там share.js или browserchannel использует некоторую другую сессию, возможно ..

Вот код:

var app = express(); 
var express = require('express'); 
... 

// SETUP AND INIT 
app.use(cookieParser()); 
app.use(bodyParser.json()); 
app.use(bodyParser.urlencoded({ 
    extended: true, 
    limit: 1024 * 1024 * 10 
})); 
app.use(methodOverride()); 
app.use(session({ 
    secret:    global.CONFIG.session.secret, 
    maxAge:    new Date(Date.now() + 1000 * 60 * 60 * 24 * 2), 
    store:    new MongoStore(global.CONFIG.mongo), 
    resave:    true, 
    saveUninitialized: true 
})); 
app.use(express.static(__dirname + '/build')); 
app.use(passport.initialize()); 
app.use(passport.session()); 
app.use(flash()); 


// Create the sharejs server instance. 
var backend = livedb.client(livedbMongo(global.CONFIG.mongo.url, false)); 
var share = sharejs.server.createClient({ 
    db: backend 
}); 
app.use(browserChannel(function(client) { 
    var stream = new Duplex({objectMode: true}); 

    stream._write = function(chunk, encoding, callback) { 
    if (client.state !== 'closed') { 
     client.send(chunk); 
    } 
    callback(); 
    }; 

    stream._read = function() { 
    }; 

    stream.headers = client.headers; 
    stream.remoteAddress = stream.address; 

    client.on('message', function(data) { 
    console.log(client.id) // <- I wish it was the same as in req.user._id.. 
    stream.push(data); 
    }); 
    stream.on('error', function(msg) { 
    client.stop(); 
    }); 
    client.on('close', function(reason) { 
    stream.emit('close'); 
    stream.emit('end'); 
    stream.end(); 
    }); 

    // Actually pass the stream to ShareJS 
    share.listen(stream); 
})); 

ответ

0

После нескольких дней проверки коды я нашел решение. Если мы посмотрим на this line in browserchannel/dist/server.js, мы увидим, что сеанс создается с использованием некоторой информации из первоначального запроса. Мы можем изменить эту часть кода, добавив

session = createSession(req.connection.remoteAddress, query, req.headers); 
// ----------- we add this ------------ 
session.user = {}; 
if(req.user) 
    session.user = req.user; 
// ------------------------------------ 

Это добавит информацию о сеансе пользователя из первоначального запроса в переменную сеанса.

1

У меня такая же проблема, и я решил ее обертыванием промежуточного конструктора browserchannel в пользовательском конструкторе:

function myMiddlewareConstructor() { 

    var request; 

    var bcMiddleware = browserChannel(function (client) { 
     //here you see the request 
    }); 

    return function (req,res,next) { 
     request = req; 
     bcMiddleware(req,res,next); 
    } 

} 

app.use(myMiddlewareConstructor()); 

Это избавляет от необходимости изменять код browserchannel.

2

Мне кажется, глядя на код, что может быть решение, которое не требует взлома модуля:

var browserChannel = require('browserchannel').server; 

var middleware = browserChannel(options, function(session, req) { 
    if (req.user) { 
    session.user = req.user; 
    } 
}); 

app.use(middleware); 

См here.

 Смежные вопросы

  • Нет связанных вопросов^_^