запрос.сессия не определена только с помощью AJAX

#javascript #jquery #ajax #node.js #express

#javascript #jquery #ajax #node.js #выразить

Вопрос:

Итак, я борюсь с этим уже пару часов. Сеанс не будет отправлен на сервер, когда я использую AJAX для отправки чего-либо на сервер, но он отлично работает без AJAX, например, переход по ссылкам, выход из системы и т. Д., И это заставляет меня нервничать. В любом случае, это мои коды:

 var express = require('express'), // express 4
mongoskin = require('mongoskin'),
Busboy = require('busboy'),
cookieParser = require('cookie-parser'),
session = require('express-session'),
mailer = require('nodemailer'),
compress = require('compression'), 
morgan = require('morgan'),
ect = require('ect'),
suspend = require('suspend'),
MongoStore = require('connect-mongo')(session);

app.use(compress());
app.engine('.ect', renderer.render);
app.set('env', 'development');
app.use(express.static(__dirname   '/public'));
app.use(cookieParser());
app.use('/admin', session({
    secret : 'qlauwork secret yo',
    name : 'qlauworks.sess',
    proxy : true,
    rolling : true,
    cookie : {
        maxAge : 1000 * 60 * 60 * 6
    },
    store : new MongoStore({
        db : 'qlauworks',
        auto_reconnect : true,
        defaultExpirationTime : 1000 * 60 * 60 * 6
    }),
    unset : 'destroy'
}));

// ... etc etc

app.post('/admin/login', function (req, res) {
    var msg = {};
    var busboy = new Busboy({ headers : req.headers });
    busboy.on('field', function (fieldName, val) {
        msg[fieldName] = val;
    });
    busboy.on('finish', function () {
        suspend.run(function * () {
            msg.password = crypto.createHash('whirlpool').update(SALT).update(msg.password).digest('hex');
            var user = yield db.users.findOne({ username : msg.username, password : msg.password }, suspend.resume());
            if (!user) {
                return res.json({ error : 'Wrong username or password' });
            }
            // create session token
            var token = yield crypto.randomBytes(32, suspend.resume());
            token = token.toString('hex');
            yield db.users.update({ username : msg.username }, { $set : { token : token } }, { upsert : true }, suspend.resume());
            req.session.token = token;
            res.redirect('/admin/forms');
        }, function (err) {
            if (err) {
                console.log('login: ', err);
                res.send('Server error');
            }
        });
    });
    req.pipe(busboy);
});

// this is the logout and forms, works just fine
app.get('/admin/logout', auth, function (req, res) {
    suspend.run(function * () {
        var token = req.session.token;
        yield db.users.update({ token : token }, { $unset : { token : true } }, suspend.resume());
        delete req.session.token;
        req.session.destroy(function (err) {
            if (!err) {
                res.clearCookie('qlauworks.sess', { path : '/' });
                res.redirect('/admin');
            }
        });
    }, function (err) {
        if (err) {
            console.log('logout: ', err);
            res.json({ error : 'Server error' });
        }
    });
});

app.get('/admin/forms', auth, function (req, res) {
    res.send(formPage);
});

// and this is the auth middleware, could logout and moving around the admin page
// but req.session always undefined if comes from an AJAX request
function auth (req, res, next) {
    suspend.run(function * () {
        console.log(req.session);
        console.log('=====================================================')
        if (!req.session.token) {
            return res.json({ error : 'Invalid token' });
        }
        var user = yield db.users.findOne({ token : req.session.token }, suspend.resume());
        if (!user.username) {
            return res.json({ error : 'Invalid token' });
        }
        next();
    }, function (err) {
        if (err) {
            console.log('auth: ', err);
            res.json({ error : 'Server error' });
        }
    });
}
  

и это на стороне клиента

 $.post('/api/item/new', elem, function (rep) {
    thisForm.find('input[type="submit"]').attr('disabled', false);
    if (rep.error) {
        $('#alert-multi').removeClass('success').addClass('alert').text(rep.error);
    } else {
        $('#alert-multi').removeClass('alert').addClass('success').text('Success');
        $('input[type="reset"]').click();
        for (var i = 0; i < len; i  ) {
            $('#preview-multi'   i).attr('src', '');
            $('#multi'   i).attr('data-image-src', '');
        }
    }
});
  

Итак, как мне это решить?

Комментарии:

1. где находится отображение /api/item/view в вашем коде на стороне сервера?

2. @soulcheck это так app.post('/api/item/:whatdo', auth, function (req, res) {

3. пожалуйста, опубликуйте все сопоставление, так как это интересная часть

4. @soulcheck Я не знаю, имеет ли это значение, потому что он даже не пройдет проверку подлинности, но я все равно опубликую его, подождите немного, прежде чем поместить его в pastebin.

5. да, в конце концов, это не имеет значения — см. Мой ответ…

Ответ №1:

Похоже, вы смонтировали промежуточное программное обеспечение сеанса /admin , но пытаетесь вызвать /api/item/view .

Это не сработает, поскольку using express.use(path, middleware) будет вызываться middleware только для запросов, которые req.url содержат path .

Либо смонтируйте промежуточное программное обеспечение сеанса / (не используя path параметр — подойдет простой express.use(middleware) ), либо измените свой ajax url для начала /admin (вероятно, это не то, что вы хотите делать).

Комментарии:

1. Черт возьми, я не могу поблагодарить вас больше, чем это. Ты просто заставляешь меня выглядеть как инструмент, и я чувствую это сейчас. Я просто потратил около 6 часов на то, чтобы решить эту проблему. Большое вам спасибо, добрый сэр.

2. Рад быть любой помощи. Иногда привлечение другой пары глаз для просмотра кода помогает больше, чем тратить часы на его изучение самостоятельно 🙂 Случалось со мной так много раз.

3. это правда. Теперь я должен помочь кому-то отплатить за услугу 🙂