I created a simple server with Express Session and Redis. The Redis server is running (I received ‘PONG’ when I typed ‘redis-cli ping’), and I declared the namespace and exported the interface SessionData to allow me to store userID on req.session (using a basic index.d.ts). However, when I make the login request, the variable userID is stored on req.session, but since the cookie is not set to the browser, it is immediately forgotten/erased. It seems like every request produces a new session and the cookie never saves.
App, Redis, and Session Cookie setup:
// ...
const app = express();
const RedisStore = connectRedis(session);
const redis = new Redis();
app.use(
session({
name: 'testcookie',
store: new RedisStore({
client: redis,
disableTouch: true,
port: 6379,
host: 'localhost',
}),
cookie: {
maxAge: 36000000 * 24 * 365,
httpOnly: true,
sameSite: 'lax',
secure: false,
},
saveUninitialized: false,
secret: 'secret',
resave: false,
})
);
// ...
Login mutation:
@Mutation(() => UserResponse)
async login(
@Arg("usernameOrEmail") usernameOrEmail: string,
@Arg("password") password: string,
@Ctx() { req }: MyContext
): Promise<UserResponse> {
// gets user via inputs (everything works here)
// ...
req.session.userID = user.id;
// userID is set to be a number, as is user.id
// logging req.session.userID works perfectly if done right here
return { user };
}
Query to check if logged in:
@Query(() => User, { nullable: true })
async me(@Ctx() { req }: MyContext): Promise<User | undefined> {
// logging req.session.userID shows undefined
return (req.session.userID)
? await User.findOne({ id: req.session.userID })
: undefined;
}
UPDATE (SOLUTION): This was resolved by going into GraphQL’s settings and changing the "request.credentials" property to "include."
2
Answers
I am following the same tutorial Fullstack React GraphQL TypeScript Tutorial in Jun 2022. Since 2021, Apollo’s GraphQL Playground does not exist- in it’s place there is Apollo studio sandbox (
https://studio.apollographql.com/sandbox/explorer
)There is no way I could find to set
request.credentials
toinclude
in the new apollo studio.After following these threads:
https://community.apollographql.com/t/allow-cookies-to-be-sent-alongside-request/920
and
https://github.com/apollographql/apollo-server/issues/5775
I came to a not-so-great solution, but that works for what I need.
Essentially, in my setup it seems like the session.cookie parameters ‘sameSite’ and ‘secure’ need to be different values depending on if you want your front end to add the cookie vs the apollo studio to add the cookie. This is NOT IDEAL – but I could not find any other combinations of parameters that worked for both. So far I’ve only found mutually exclusive settings.
On my server’s index.ts
I use this session setup when I want to set cookie from front-end localhost:3000
I actually change the session setup if I want to set the cookie and session userId from the apollo studio
I use this session setup when I want to set cookie from backend-end localhost:4000/graphql
Please comment if you know of a way to use the same settings to allow cookies from both front and backend.
For those of you who are following the tutorial and want more details, here are the other important parts of the setup.
This is my entire index.ts file from backend. Note – I am 8.5 hours into the tutorial – so don’t worry if you don’t recognize some parts.
Here is my data-source (the new way to make typeORM connection!)
in the createUrqlClient.tsx front end file, I have added
Here is a snapshot of the settings needed in apollo studio. To open these settings, click on the settings/gear icon at the top left inside the SANDBOX input.
make sure to add ‘x-forwarded-proto’ ‘https’ to the Shared Headers.
The answer form @NicoWheat is partial right (I guess, correct me if I am wrong). It worked when I send the request with apollo studio (with sameSite:"none" and secure: true) but regardless what are the options the cookies still has not been set for me when I do the mutation through localhost:3000.
Edit: I was wrong, after following the option in create urql client in frontend directory, it worked for me, thanks and appreciate it a lot.