0

I can't figure out why when i goto localhost:8080 it saves the session (appears to) but then when I goto the next URL localhost:8080/me the session is empty again.

const express = require("express");
const app = express();
const port = 8080;
const router = express.Router();
const session = require('express-session');

app.use(session({
  secret: 'work hard',
  resave: true,
  saveUninitialized: false
}))

app.get("/", function(req,res, next){
    req.session.myname = "nathan";
    console.log(req.session.myname);
});


app.get("/me", function(req,res, next){

    console.log(req.session.myname);
});

app.listen(port, () => console.log(`Example app listening on port ${port}!`))

when I try the app.sendStatus method as shown by the first contributor below (in the answers), it works, but not if I use ajax???

    $("#register").on("click", function(){
         $.ajax({url: "http://localhost:8080/"});
    });


    $("#me").on("click", function(){
         $.ajax({url: "http://localhost:8080/me"});
    });
Nathan Leggatt
  • 196
  • 1
  • 13

1 Answers1

1

The reason is you didn't send a response with a set-cookie header to client.

The Set-Cookie HTTP response header is used to send cookies from the server to the user agent, so the user agent can send them back to the server later.

You can use res.sendStatus(), res.send(), res.end() and res.json() etc. Send a response to client.

E.g.

app.js:

const express = require('express');
const app = express();
const port = 8080;
const router = express.Router();
const session = require('express-session');
const fs = require('fs');
const path = require('path');

app.use(
  session({
    secret: 'work hard',
    resave: true,
    saveUninitialized: false,
  }),
);

app.get('/', function(req, res, next) {
  req.session.myname = 'nathan';
  console.log(req.session.myname);
  const htmlContent = fs.readFileSync(path.resolve(__dirname, './public/app.html')).toString();
  res.send(htmlContent);
});

app.get('/me', function(req, res, next) {
  console.log(req.session.myname);
  res.sendStatus(200);
});

app.get('/ajax', function(req, res) {
  console.log('req.session.myname: ', req.session.myname);
  res.sendStatus(200);
});

app.listen(port, () => console.log(`Example app listening on port ${port}!`));

After doing this, your client(can be a browser) will receive these response headers:

HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/plain; charset=utf-8
Content-Length: 2
ETag: W/"2-nOO9QiTIwXgNtWtBJezz8kv3SLc"
set-cookie: connect.sid=s%3A-QI2kuY8IlxdAZw96xqG_npmuKwFhg0s.tKcPZgcHhHvXG0kqgKzwzJJ7kn2JkPOMG9R%2FyQaJwPw; Path=/; HttpOnly
Date: Mon, 23 Dec 2019 06:00:24 GMT
Connection: keep-alive

The browser will set cookie automatically. Then, you goto the next /me route, the browser will send this cookie automatically with request header.

E.g.

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cache-Control: no-cache
Connection: keep-alive
Cookie: connect.sid=s%3A-QI2kuY8IlxdAZw96xqG_npmuKwFhg0s.tKcPZgcHhHvXG0kqgKzwzJJ7kn2JkPOMG9R%2FyQaJwPw
Host: localhost:8080
Pragma: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36

In your server side /me controller, express-session middleware will parse the cookie and you will get the value of myname from req.session.myname property.

Update:

./public/app.html:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
  </head>
  <body>
    <main>
      app
      <button id="me">Click Me</button>
    </main>
    <script
      src="https://code.jquery.com/jquery-3.4.1.min.js"
      integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
      crossorigin="anonymous"
    ></script>
    <script>
      window.onload = function() {
        $('#me').on('click', function() {
          $.ajax({ url: 'http://localhost:8080/ajax' }).then(() => {
            console.log('success');
          });
        });
      };
    </script>
  </body>
</html>

You can get the value of myname as well. Here is the server-side logs:

Example app listening on port 8080!
nathan
        req.session.myname:  nathan
slideshowp2
  • 38,463
  • 29
  • 127
  • 255