Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

req.session.get() returns undefined, but cookie is set #305

Closed
ppalmeida opened this issue Feb 12, 2021 · 9 comments
Closed

req.session.get() returns undefined, but cookie is set #305

ppalmeida opened this issue Feb 12, 2021 · 9 comments

Comments

@ppalmeida
Copy link

I'm probably missing something here, but inside getServerSideProps if I call req.session.get('user') it returns undefined. But when I check the req object:

  • req.cookies has the user key with the token as its value
  • req.headers.cookie also shows the user=abce3234 token value.

What am I missing here?

My hope was to do req.session.get('user') and get the JWT decoded value (like

{ 
  id: 1, 
  name: 'John Doe', 
  login: 'joh@doe.com',  
  // etc...
 }`

Or, if not possible, get at least the token string, so I can manually decode it.

Thank you in advance for any help.

Screenshot 2021-02-12 at 02 41 32

@vvo
Copy link
Owner

vvo commented Feb 16, 2021

Hey there, can you provide a simple example (starting from the Next.js example of this repository) that can reproduce this issue?

PS: You have to call req.session.set("user") if you want to get the user with req.session.get("user"). The fact that the cookie is named "users" and req.session.get("user") are two different things (one is cookie name, the other is serialized data inside the cookie value).

@luispastendev
Copy link

It makes me very strange, right now I am having the same problem but it seems to be intermittent, I have done some tests by starting and closing session, but sometimes it returns the values of the cookie and other times it does not. seems to be a time issue.

set cookies
imagen

call value
imagen

sometimes it returns and sometimes it doesn't
imagen

:(

@luispastendev
Copy link

luispastendev commented Mar 4, 2021

I was reviewing my code and in my case it was a problem of the flow of my application but req.session.get() works fine for my part I do not see problems.

@Bexy-Lyn
Copy link

Bexy-Lyn commented Mar 19, 2021

Hey there,

so I am running into a similar issue.
I am working with Next.js for my client and Node.js, Express, Sequelize and MySQL for my backend in a seperate repo.

The thing that is driving me nuts is, that the cookie is set correctly in my "/login" and "/signup" routes and even req.session.destroy() works as expected on "/logout". Just req.session.get("user") returns an emty object on refresh. The cookie survives refresh though.

This is my code in the "user.js" route:

const express = require("express");
const router = express.Router();
const { User, Pet } = require("../sql/sequelize");
const passwordHash = require("password-hash");
const Sequelize = require("sequelize");
const { or } = Sequelize.Op;
const fs = require("fs");
require("dotenv");
const { ironSession } = require("next-iron-session");

const session = ironSession({
  cookieName: "session",
  password: [
    {
      id: 1,
      password: process.env.SESSION1,
    },
    {
      id: 2,
      password: process.env.SESSION2,
    },
  ],
  
  cookieOptions: {
    secure: process.env.NODE_ENV !== "production",
    httpOnly: true,
    sameSite: "strict",
    path: "/",
  },
});

router.put("/login", session, (req, res) => {
  if (valueMissing(req.body.name) || valueMissing(req.body.pw))
    return res.json({ error: "missing", loggedIn: false });
  else {
    User.findAll({
      where: { [or]: [{ name: req.body.name }, { mail: req.body.name }] },
    }).then((data) => {
      if (typeof data[0] == "undefined")
        return res.json({ error: "wrongName", loggedIn: false });
      else if (!passwordHash.verify(req.body.pw, data[0].pw))
        return res.json({ error: "wrongPW", loggedIn: false });
      else {
        const key = createKey();
        User.update({ key: key }, { where: { id: data[0].id } }).then(() => {
          User.findAll({ where: { key: key } }).then((data) => {
            req.session.set("user", { key: key });
            req.session.save().then(() => {
              console.log("session-key: " + req.session.get("user").key); //session set properly
              return res.json({
                name: data[0].name,
                mail: data[0].mail,
                id: data[0].id,
                loggedIn: true,
                verified: data[0].verified,
              });
            });
          });
        });
      }
    });
  }
});

router.get("/update", session, async (req, res) => {
  console.log("session: " + JSON.stringify(req.session)); //empty object, session is set though
  if (valueMissing(req.session.get("user")) || valueMissing(req.session.get("user").key))
    return res.json({ error: "missing", loggedIn: false });
  else {
    console.log("Key: " + req.session.get("user").key);
    User.findAll({ where: { key: req.session.get("user").key } }).then(
      (data) => {
        console.log("users searched for key");
        if (typeof data[0] == "undefined") {
          req.session.destroy();
          return res.json({ error: "invalidKey", loggedIn: false });
        } else {
          console.log("user found");
          console.log("Key: " + data[0].key);
          return res.json({
            name: data[0].name,
            mail: data[0].mail,
            id: data[0].id,
            loggedIn: true,
            verified: data[0].verified,
          });
        }
      }
    );
  }
});

router.put("/logout/:id", session, async (req, res) => {
  User.update({ key: "" }, { where: { id: req.params.id } }).then(() => {
    req.session.destroy(); //session is not longer set
    return res.json({ msg: "loggedOut" });
  });
});

Has anyone an idea? I have been struggling with this for some time now and am grateful for anything that might help.
Thanks!

@vvo
Copy link
Owner

vvo commented Mar 24, 2021

I've just experienced a similar issue, make sure that all your URLs are in https (or on the same protocol if you're not using the secure option), the one doing the req.session.save() and the one reading the session.

For example, I was on an http://example.com/redirect api route and used session.save(), this route redirects to slack.com, which then redirects to https://example.com (mind the https) and it failed to read the session: it's on a different protocol.

@vvo
Copy link
Owner

vvo commented Mar 24, 2021

@Bexy-Lyn I see you're using sameSite: strict. Be aware that when cookies are strict, they are not sent if you open a new tab to your website. They are only sent when you navigate (click) from yoursite.com/page1 to yoursite.com/page2.

If you click on a link to yoursite.com from gmail: cookies are not sent by the browser.
If you open a new tab to yoursite.com: cookies are not sent by the browser.

@vvo
Copy link
Owner

vvo commented Mar 24, 2021

I think we've pretty much covered what can cause your session to "not be here":

If someone still has problems, open a new issue with a GitHub repository reproducing the issue, thanks!

@vvo vvo closed this as completed Mar 24, 2021
@FauzanKhan
Copy link

I'm facing the same issue. For me, the req.session.get('user') returns undefined even on the 2nd pass through the same endpoint on the same page.

Below is my api handler –

const handler = async function (req, res) {
  console.log(req.session.get('user')); // returns undefined even after the session is set below
  if (req.method === 'POST') {
    const { email, password } = req.body;
    const user = await prisma.user.findUnique({
      where: {
        email,
      },
    });

    const isPasswordValid = bcrypt.compareSync(password, employer.password);
    if (isPasswordValid) {
      req.session.set('user', {
        id: user.id,
      });
      await req.session.save();

      console.log('saved session', req.session.get('user')); //returns saved session

      res.status(200).send({});
    }

    res.status(500).send();
  }
};

@fcpauldiaz
Copy link

I have the same problem. req.session.get('user') works inside ServerSideProps but doesn't work inside API Routes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants