Git Product home page Git Product logo

Comments (29)

RiahiKarim avatar RiahiKarim commented on July 21, 2024 54

@dzirg44 This should work.

import { Request, Response } from 'express';
import { Session, SessionData } from 'express-session';

export type MyContext = {
  req: Request & {
    session: Session & Partial<SessionData> & { userId?: number };
  };
  res: Response;
};

from lireddit.

benawad avatar benawad commented on July 21, 2024 49

Looks like the session type has been removed from express, you could probably just do:

Request & { session: { userId: string } };

from lireddit.

c2peng avatar c2peng commented on July 21, 2024 17

Thanks so much for asking this. Spent 6+ hrs trying to figure out what's happening.

from lireddit.

Tenezill avatar Tenezill commented on July 21, 2024 6

I have tried several methods and for whatever reason, there is not a cookie being saved...

hey, the thing that solved the problem for me was "removing" secure while in development.
like this:

app.use(
    session({
      name: "qid",
      store: new RedisStore({
        client: redisClient,
        disableTouch: true,
      }),
      cookie: {
        maxAge: 1000 * 60 * 60 * 24 * 365 * 1, // 10 years
        httpOnly: true,
        sameSite: "lax", // csrf
        // secure: __prod__, // cookie only works in https
      },
      saveUninitialized: false,
      secret: "qowihho",
      resave: false,
    })
  );

from lireddit.

girishk21 avatar girishk21 commented on July 21, 2024 5

I found this to be working!

in /server/index.d.ts

import { User } from './src/entities/User';

declare global {
  namespace Express {
    interface Session {
      userid?: number;
    }
  }
}

and add this to "files": [] attribute of tsconfig.json.

Express.Session is now available in /server/src/types.ts 🎉

is it okay to play with declaration merging or it's not advisable to do so?

from lireddit.

mattrgibson avatar mattrgibson commented on July 21, 2024 3

Don't forget to ensure that the GraphQL playground settings have credentials to include. This took me an hour to remember that Ben mentioned this very early on in the video:

image

from lireddit.

Sparklytical avatar Sparklytical commented on July 21, 2024 1

I did something like this -

interface SessionData {
  userId: number;
}

export type Context = {
  req: Request & { session: SessionData };
};

from lireddit.

sandeep-v1404 avatar sandeep-v1404 commented on July 21, 2024 1

Looks like the session type has been removed from express, you could probably just do:

Request & { session: { userId: string } };

It should be

Request & { session: { userId?: number } }

because again in UserResolver me( ) Query, Id is a number.

const user = em.findOne(User, { id: req.session.userId }); // where id is a number.

from lireddit.

skele2k avatar skele2k commented on July 21, 2024 1

I have tried several methods and for whatever reason, there is not a cookie being saved...

maybe you should check your constant
it must be
export const __prod__ = process.env.NODE_ENV === "production";
not
export const __prod__ = process.env.NODE_ENV !== "production";

from lireddit.

amarkmcconn avatar amarkmcconn commented on July 21, 2024 1

This post helps fix the the switch from playground to sandbox if you are unable to test the cookie login

https://stackoverflow.com/questions/69333408/express-session-does-not-set-cookie/70673115#70673115

from lireddit.

uV3301 avatar uV3301 commented on July 21, 2024

@dzirg44 This should work.

import { Request, Response } from 'express';
import { Session, SessionData } from 'express-session';

export type MyContext = {
  req: Request & {
    session: Session & Partial<SessionData> & { userId?: number };
  };
  res: Response;
};

This worked fine. Thanks @dzirg44

from lireddit.

MananDesai54 avatar MananDesai54 commented on July 21, 2024

@dzirg44 This should work.

import { Request, Response } from 'express';
import { Session, SessionData } from 'express-session';

export type MyContext = {
  req: Request & {
    session: Session & Partial<SessionData> & { userId?: number };
  };
  res: Response;
};

Thank you, it worked

from lireddit.

MananDesai54 avatar MananDesai54 commented on July 21, 2024

Looks like the session type has been removed from express, you could probably just do:

Request & { session: { userId: string } };

Your videos are on the next level, thank you so much for all of this

from lireddit.

CarlosBalladares avatar CarlosBalladares commented on July 21, 2024

This solves too

import session from "express-session";
...
Request & { session: session.Session & { userId?: number } };

from lireddit.

ahmedrowaihi avatar ahmedrowaihi commented on July 21, 2024

import session from "express-session";
declare module "express-session" {
interface SessionData {
userId?: number;
}
}

export type MyContext = {
req: Request & { session: session.Session & Partial<session.SessionData> };
res: Response;
redis: Redis;
usersLoader: ReturnType;
updootLoader: ReturnType;
};

from lireddit.

BookmDan avatar BookmDan commented on July 21, 2024

I have tried several methods and for whatever reason, there is not a cookie being saved...

from lireddit.

benawad avatar benawad commented on July 21, 2024

@BookmDan this is all my advice for debugging cookies: https://benawad.com/cookie

from lireddit.

BookmDan avatar BookmDan commented on July 21, 2024

Thank you @benawad That was helpful. Actually, because we are incorporating with RedisStore would that be considered a 3rd Party Cookie? Asking for a friend.

from lireddit.

BookmDan avatar BookmDan commented on July 21, 2024

This is the error message that I am seeing:

Screen Shot 2021-01-02 at 8 15 50 AM (2)

from lireddit.

kyawthura-gg avatar kyawthura-gg commented on July 21, 2024

I have tried several methods and for whatever reason, there is not a cookie being saved...

I have solved this by setting cors in apollo server.

apolloServer.applyMiddleware({
app,
cors: {
credentials: true,
},
});

from lireddit.

matthew-d-stringer avatar matthew-d-stringer commented on July 21, 2024

According to express-session, this is what I did:

import { Request } from "express";
import session from "express-session";

declare module "express-session" {
  interface SessionData {
    userId?: number;
  }
}

export type MyContext = {
  req: Request & { session: session.SessionData };
  res: Response;
};

You can see where I got this idea in the Type definition for session.SessionData (ctrl+right click in VsCode):

    /**
     * This interface allows you to declare additional properties on your session object using [declaration merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html).
     *
     * @example
     * declare module 'express-session' {
     *     interface SessionData {
     *         views: number;
     *     }
     * }
     *
     */
    interface SessionData {
        cookie: Cookie;
    }

from lireddit.

ahmedrowaihi avatar ahmedrowaihi commented on July 21, 2024

I guess this issue has to be closed! like all solutions here do work fine!

from lireddit.

BookmDan avatar BookmDan commented on July 21, 2024

from lireddit.

SSouper avatar SSouper commented on July 21, 2024

Yes I'm having a similar issue. On to the next project for now...

It seems like the apollo middleware removes every field from req that "should not be there" (session included). I put a middleware function before apollo but after express-session and req.session was there.

from lireddit.

benawad avatar benawad commented on July 21, 2024

do you get the same result if you clone my code?

from lireddit.

SSouper avatar SSouper commented on July 21, 2024

@benawad looks like i forgot to destructure the first argument to the context function. Strangely, typescript didn't tell me that i'm a bad boy...

from lireddit.

AaronMcCloskey avatar AaronMcCloskey commented on July 21, 2024

@dzirg44 This should work.

import { Request, Response } from 'express';
import { Session, SessionData } from 'express-session';

export type MyContext = {
  req: Request & {
    session: Session & Partial<SessionData> & { userId?: number };
  };
  res: Response;
};

Trying this method has resulted in this error for me

node_modules/@types/connect-redis/index.d.ts:32:72 - error TS2694: Namespace 'global.Express' has no exported member 'SessionData'.

    ttl?: number | string | ((store: RedisStore, sess: Express.SessionData, sid: string) => number);
    

Package.json

devDependencies": {
    "@types/connect-redis": "^0.0.14",
    "@types/express": "^4.17.7",
    "@types/express-session": "^1.17.0",
    "@types/node": "^14.0.27",
    "@types/redis": "^2.8.25",
    "nodemon": "^2.0.4",
    "ts-node": "^8.10.2",
    "typescript": "^3.9.7"
  },
  "dependencies": {
    "@mikro-orm/cli": "^4.0.0-alpha.0",
    "@mikro-orm/core": "^4.0.0-alpha.0",
    "@mikro-orm/migrations": "^4.0.0-alpha.0",
    "@mikro-orm/postgresql": "^4.0.0-alpha.0",
    "apollo-server-express": "^2.16.1",
    "argon2": "^0.26.2",
    "class-validator": "^0.13.1",
    "connect-redis": "^5.0.0",
    "express": "^4.17.1",
    "express-session": "^1.17.1",
    "graphql": "^15.3.0",
    "pg": "^8.3.0",
    "redis": "^3.0.2",
    "reflect-metadata": "^0.1.13",
    "type-graphql": "^1.0.0-rc.3"
  },

The solution I found was adding this, but it feels kind of hacky, is there a better solution?

declare global {
  namespace Express {
    interface SessionData {
      cookie: any;
    }
    interface Session {
      userId?: number;
    }
  }
}

from lireddit.

Deveshb15 avatar Deveshb15 commented on July 21, 2024

Don't forget to ensure that the GraphQL playground settings have credentials to include. This took me an hour to remember that Ben mentioned this very early on in the video:

image

When I change it from "omit" to "include" I get this error, any solution for this?

image

and I get this cors error in the console
image

from lireddit.

gierle avatar gierle commented on July 21, 2024

I found a weird behaviour and can't really explain why this is:

When setting the req.session.userId to the uid in login or register, the mutation gets executed properly, but the frontend never revieves a response. But when i don't set the 'userID', a response is recieved.

So for example the following code

req.session.userId = user._id; 
console.log(req.session) // this gets printed 
return { user };

would print the session object with cookie and userId, but the frontend never leaves the fetching state and eventually times out.
The same for the playground btw


The solution is an incompatibility between connect-redis and node-redis as described in this issue:
tj/connect-redis#336

Replace this line in index.ts
const redisClient = createClient({ legacyMode: true });

from lireddit.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.