0

This is a code that works by checking if the inputs someone registered in login page exists in the database or not. It works and all. However, when I wanted to set a cookie(I just wanted to set it randomly so I see if it works) so that I can save its state as online, an error has happened

Cannot set Headers after they are sent

I understand from this that is because I did res.render and res.cookies at the same request or something like that, however, I removed res.render and kept res.cookies, the error is gone but even then it didn't register any cookies(No cookies at network panel of dev tools nor by writing document.cookie at console)

I also tried to move that code to the request get when rendering the page but it still doesn't work.

This is the server code:

// Importing modules/packages
let connection = require("./Connection.js");
let bodyParser = require("body-parser");
var cookieParser = require("cookie-parser");
let express = require("express");
let app = express();
app.use(cookieParser());
let urlencodedParser = bodyParser.urlencoded({ extended: false });

// Server and routing
app.listen(3000, function() {
  console.log("The server at port 3000 is open!");
});
app.set("view engine", "ejs");
app.get("/Signup", (req, res) => {
  res.render("Register");
});
app.get("/", function(req, res) {
  res.redirect("Login");
});
app.get("/Login", function(req, res) {
  res.render("Login");
});

// Database's Connection
connection.connect(err => {
  if (err) {
    throw "ERROR! " + err;
  }
  console.log("Has connected to MySQL Database!");
});

// Requesting and Receiving Data from body parser
app.post("/Signup", urlencodedParser, function(req, res) {
  console.log(req.body);
  res.render("Register");
  connection.query(
    `insert into users (Username, User_Password, Email_Address) values ("${
      req.body.Username
    }", ${req.body.Password}, "${req.body.Email}")`,
    function(err) {
      if (err) throw "An error has happened while excuting the query " + err;
      console.log("Query got excuted successfully!");
    }
  );
});

app.post("/Login", urlencodedParser, (req, res) => {
  connection.query(
    `SELECT Username FROM users WHERE User_Password = ${
      req.body.Password
    } AND Username = "${req.body.Username}"`,
    function(err, results) {
      if (results.length === 0) {
        console.log(
          "Sorry, this username/password doesn't exist in our database."
        );
      } else {
        console.log("Logined successfully!");
        res.cookie("Friend", "Jack");
      }
    }
  );
  res.render("Login");
});

I also tried to read the cookies by using req.cookie("Friend") but it didn't work. I don't know what's the problem.

How I can solve this please?

Boy pro
  • 452
  • 4
  • 19

1 Answers1

2

You are setting cookies in callback but rendering outside callback, it should be like this:

app.post("/Login", urlencodedParser, (req, res) => {
  connection.query(
    `SELECT Username FROM users WHERE User_Password = ${
      req.body.Password
    } AND Username = "${req.body.Username}"`,
    function(err, results) {
      if (results.length === 0) {
        console.log(
          "Sorry, this username/password doesn't exist in our database."
        );
      } else {
        console.log("Logined successfully!");
        res.cookie("Friend", "Jack");
      }
      res.render("Login"); // <-- moved here
    }
  );
});

Code in Node.js is generally not executed sequentially - this is because of asynchronous nature (I wrote something more about that here).

app.post("/path", (req, res) => {
  // 1
  connection.query(query, () => {
    // 3 after query has been executed
    res.cookie("Friend", "Jack");
  });
  // 2
  res.render("Login");
});

In your code the execution goes like this:

  1. connection.query is executed but given the callback the rest of the code is not waiting for query to finish, instead it goes to the next statement
  2. res.render("Login"); which is going to render the result to the browser
  3. The query is finally executed and result is returned to the callback where we try to set res.cookie - which is going to fail at this point.

Also note your code as is contains SQL injection vulnerabilities. You should fix those before deploying to production!

m1ch4ls
  • 3,317
  • 18
  • 31
  • Wow, thank you so much! Never thought of this! And yeah, it has many vulnerabilites but that's just because of development, it's still a very good advice and information. Still, I don't understand why moving it to the callback function fixed it. Can you clear it up a little more please? – Boy pro Aug 24 '18 at 18:41