Как остановить последовательность промежуточного программного обеспечения после продолжения маршрута end () в выражении node.js

1
  • Пожалуйста помоги. Я не могу понять, что я делаю что-то неправильно или это то, как все работает.
  • Это просто приложение для входа/регистрации. Я использую промежуточное программное обеспечение, чтобы пользователь не мог попасть на главную страницу, если они не вошли в систему на основе проверки cookie. Единственные маршруты, которые доступны, если вы не вошли в систему, - это GET/POST/login и GET/POST/register, после того, как их объявление станет промежуточным программным обеспечением, которое проверяет, есть ли у пользователя специальный файл cookie, если нет, пользователь будет перенаправлен на GET/логин, и он работает нормально.

Вы можете просмотреть весь код, если необходимо, на GitHub: MNEVO


существует три основных посредника:

  1. cookieparse (parse cookie с запросом)
  2. session (запишите файл cookie и напишите его на req.cookie.user)
  3. validate (если бы шифр был моим, тогда вы получите JSON из cookie, если нет, это будет неопределенным)

Я вставил console.log в каждый (кроме анализатора файлов cookie) и в логин.


И это то, что вывод я получаю, что собирается GET/логин:

 login:  1515262934656  
 session:  1515262935709  
 validation:  1515262935709 

  • Проблема в том, что когда пользователь пытается войти в систему, и он это сделал, и маршрут POST/login закрывает соединение, отвечающее с перенаправлением на GET/главную страницу и записывая cookie пользователю,
.post((req,res)=>{
    var user = req.body;
    //validate input
    s2m.login(user , (s2mres)=>{
        if(s2mres.statusCode === 200){
            res.set("Set-Cookie", 'one = ${session.getOneCookie(user)}}; Path='/'');
            res.set("Location", "/main");
            res.status(302).end();
        }else{
            res.set("Location", "/login");
            res.status(302).end();
        }
    });
});
  • этот middlewares все еще пытается продолжить, и поскольку у пользователя нет cookie, в первую очередь, промежуточное программное обеспечение пытается перенаправить его на страницу GET/login, и, конечно же, он терпит неудачу, потому что предыдущий маршрут POST/login уже закрыт. клиент.
LOGIN success:  1515264690286
session:  1515264690378
validation:  1515264690379 // Im redirected to register page at this point(I think)
Error: Can't set headers after they are sent.
    at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:356:11)
    at ServerResponse.header (/home/ubuntu/workspace/node_modules/express/lib/response.js:767:10)
    at ServerResponse.send (/home/ubuntu/workspace/node_modules/express/lib/response.js:170:12)
    at app.get (/home/ubuntu/workspace/server/server.js:86:6)
    at Layer.handle [as handle_request] (/home/ubuntu/workspace/node_modules/express/lib/router/layer.js:95:5)
    at next (/home/ubuntu/workspace/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/home/ubuntu/workspace/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/home/ubuntu/workspace/node_modules/express/lib/router/layer.js:95:5)
    at /home/ubuntu/workspace/node_modules/express/lib/router/index.js:281:22
    at Function.process_params (/home/ubuntu/workspace/node_modules/express/lib/router/index.js:335:12)
session:  1515264691190
validation:  1515264691191
  • Вопрос: есть ли способ разбить промежуточную последовательность после того, как предыдущий маршрут уже закрыт, или я ошибаюсь, и есть какой-то другой способ?

приложение

var env = require("./env.js");
var app     = require("express")();
var session = require("./session/session.js");
var cookieparser = require("cookie-parser");
var bp        = require("body-parser");
var setCookie = require("set-cookie");
var pug     =   require("pug");
var s2m = require("./s2m/s2m.js");

const ENVIRONMENT = env.c9;


app.get("/get-login-css", (req,res)=>{
    res.sendFile(__dirname+"/client/css/login.css");
});

app.use(bp.urlencoded({ extended: false }));

app.route("/register")
    .get((req,res)=>{
        res.send(pug.renderFile("./pugs/register.pug",{})).status(200).end();
    })
    .post((req,res)=>{
        var user = req.body;
        //validate input
        s2m.register(user, (s2mres)=>{
            if(s2mres.statusCode === 200){
                res.set("Set-Cookie", 'one = ${session.getOneCookie(user)}; Path='/'');
                res.set("Location", "/main");
                res.status(302).end();
            }else{
                res.set("Location", "/login?notification=wrong%20login%20or%20password");
                res.status(302).end();
            }
        });
    });

app.route("/login") 
    .get((req,res)=>{
        console.log("login: ",Date.now());
        res.end(pug.renderFile("pugs/login.pug" , {notification: req.query.notification}));
    })
    .post((req,res)=>{
        var user = req.body;
        //validate input
        s2m.login(user , (s2mres)=>{
            if(s2mres.statusCode === 200){
                res.set("Set-Cookie", 'one = ${session.getOneCookie(user)}}; Path='/'');
                res.set("Location", "/main");
                res.status(302).end();
            }else{
                res.set("Location", "/login");
                res.status(302).end();
            }
        });
    });

app.get("/logout",(req,res)=>{
    res.set("Set-Cookie", 'one = ${undefined}; Path='/'');
    res.set("Location", "/login");
    res.status(302).end();
});


//YOU SHALL NOT PASS (if you don't have login in your cookies)
app.use(cookieparser());
app.use(session.session());
app.use(session.validate());

//ROUTS
app.get("/view-cookie",(req,res)=>{
    console.log("this is bad");
    //user is exist if the code get thus far. so what we well do with it ?
    var user = req.cookies.user;
    //redirect to the home page
    res.send(JSON.stringify(user));
});

app.get("/",(req,res)=>{
    res.set("Location", "/main");
    res.status(302).end();
});

app.get("/main",(req,res)=>{
    res.send("<div style='text-align: center'> <h1>WELCOME</h1> <br> <a href='/logout'>LOGOUT</a> </div>");
});


app.listen(ENVIRONMENT.port, (err,port)=>{
    if(!err){
        console.log("WE ROLLING! on: ", ENVIRONMENT.domain);
    }
});

session.js

var encdec = require("./encdec.js");
var cookie = require("./cookie.js");

var find = function(cipher){
    try{
        return JSON.parse(encdec.decrypt(cipher));
    }catch(err){
        return undefined;
    }
};

var session = function(callback){
    return function(req,res,next){
        console.log("session: ",Date.now());
        req.cookies.user = find(req.cookies.one);
        next();
    };
};

var validate = function(callback){
    return function(req,res,next){
        console.log("validation: ",Date.now());
        if(!req.cookies.user){
            res.redirect("/register");
            // res.status(302).end();
        }
        next();
    }
}

var getOneCookie = function(obj){
    return encdec.encrypt(JSON.stringify({array: cookie.wrap(obj)}));
};


module.exports = {
    session,
    validate,
    getOneCookie
};
Теги:
express
middleware

2 ответа

0
Лучший ответ
  • Это был момент обмана с выходом. Проблема заключалась только в одной закрывающей фигурной скобке в строке String.

    - Но, отвечая на мой собственный вопрос, ответы:


последовательность промежуточного программного обеспечения автоматически прекращается с завершением цикла req\res, как указано в официальной документации,


независимо от того, закрываю ли я соединение с переадресацией или концом или конечным состоянием, пока я закрываю соединение. Благодаря вашему вниманию. Надеюсь, он убедит других в надежности документации на данный момент, о чем я сомневался.

2

Вы делаете несколько вещей в неправильном порядке. res.send() отправляет ответ прямо там. Любая попытка сделать дальнейшие действия с этим запросом вызовет ошибку, которую вы видите.

Итак, измените это:

res.send(pug.renderFile("./pugs/register.pug",{})).status(200).end();

к этому:

res.send(pug.renderFile("./pugs/register.pug",{}));

.status(200) по умолчанию, поэтому вам не нужно его устанавливать. И, res.send() отправляет запрос, поэтому вам не нужно .end() после него.

Если вы все еще хотите установить статус, вы должны сначала установить его:

res.status(200).send(pug.renderFile("./pugs/register.pug",{}));

Некоторые другие комментарии.

Вы можете заменить этот тип последовательности:

res.set("Location", "/login");
res.status(302).end();

с этим:

res.redirect("/login");

Кроме того, вы должны иметь возможность подключать мопс прямо в систему рендеринга в Express, чтобы вы могли просто использовать это:

res.render("./pugs/register.pug", {})

вместо:

res.send(pug.renderFile("./pugs/register.pug",{}))
  • 0
    Спасибо и все, но это не то, что я просил. Дело в том, почему промежуточное программное обеспечение срабатывает, даже когда ответное соединение было закрыто.
  • 0
    @GrenudiIdunerg - я не думаю, что вы правильно оценили проблему. Какое промежуточное программное обеспечение, по вашему мнению, запускается, даже если запрос выполнен? Вы исправили все случаи этого и попробовали это?
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню