My cookie is not set in Browser of studio.apollographql explorer - node.js

i am trying to set cookie on apollo Studio explorer, my redis setup successfully store the cookie, but nothing is set on the browser.
Please What am i doing wrong ?
when make a monitoring of redis with redis-cli ,i can see that the token is receive.
i am using : apollo-server-express "^3.3.0", and express-session "^1.17.2"
async function startServer() {
const app = express();
const httpServer = http.createServer(app);
const RedisStore = connectRedis(session);
const redisClient = redis.createClient({
host: "127.0.0.1",
port: 6379,
});
app.use(
session({
name: "pid",
store: new RedisStore({
client: redisClient,
}),
cookie: {
maxAge: 1000 * 60 * 10,
httpOnly: false,
secure: true,
sameSite: "none",
},
saveUninitialized: false,
secret: "EOJ7OmvIAhb2yJpCI947juj6F8CppHCp",
resave: false,
})
);
const server = new ApolloServer({
schema,
context: createContext,
formatError: (error) => {
return {
message: error.message,
};
},
});
await server.start();
server.applyMiddleware({
app,
cors: { credentials: true, origin: "https://studio.apollographql.com" },
});
await new Promise((resolve: any) =>
httpServer.listen({ port: process.env.PORT }, resolve)
);
}
startServer().catch((err) => console.log(err));

Related

Nest.js express-session Set-Cookie header is not working - CORS issue

I've got the frontend and backend on different servers. when I first deployed the services I've got "SameSite: none" because of different origins, then when I set it to none, it required me to set "Secure: true" as well, after setting that I'm unable to see the Set-cookie header on server's response and on production the cookie is just not recieved.
here's main.ts with the express-session middleware:
async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule);
const sessionSecret = app.get(AppConfigService).getConfig().session.secret;
const frontDomain = app.get(AppConfigService).getConfig().front.domain;
const port = app.get(AppConfigService).getConfig().app.port;
app.setGlobalPrefix('api');
app.use(
session({
name: 's.id',
secret: sessionSecret,
resave: false,
saveUninitialized: false,
cookie: {
maxAge: 360000, // 1hour in seconds
secure: process.env.NODE_ENV !== 'production' ? false : true,
},
store: new PrismaSessionStore(new PrismaClient(), {
checkPeriod: 2 * 60 * 1000, //ms
dbRecordIdIsSessionId: true,
dbRecordIdFunction: undefined,
}),
}),
);
app.enableCors({
origin: [frontDomain, `${frontDomain}/`],
credentials: true,
});
app.use(passport.initialize());
app.use(passport.session());
await app.listen(port);
}
bootstrap();
try this, it works for me
const app = await NestFactory.create<NestExpressApplication>(AppModule{cors: true,});

My req.session from Express is undefined, nothing works

I searched a lot to fix my problem but nothing works, the req.session is undefined, what am I doing wrong ?
In server.js :
const app = express();
const session = require('express-session');
const redis = require('redis');
const redisClient = redis.createClient();
async function connectRedis() {
try {
const redisStore = require('connect-redis')(session);
await redisClient.connect();
app.use(
session({
name: '_redisPractice',
secret: 'myStackOverflowkey',
saveUninitialized: true,
cookie: { maxAge: 1000 * 60 * 60 * 24, secure: false, httpOnly: true },
resave: false,
store: new redisStore({ host: 'localhost', port: 6379, client: redisClient, ttl: 86400 }),
}),
);
} catch (err) {
console.log(err);
}
}
connectRedis();
app.post('/api/auth/signin', (req, res) => {
console.log('Well.....', req.session);
});
The redis-CLI's monitor doesn't show anything, same for my server.
Thank you in advance

UnhandledPromiseRejectionWarning: Error: The client is closed on NodeJS

I am trying to add Redis to my website for session management but I get the below error:
UnhandledPromiseRejectionWarning: Error: The client is closed
Below is my code:
I have kept only the relevant redis lines to avoid verbosity.
const express = require('express');
const app = express();
const session = require('express-session');
const redis = require('redis');
const connectRedis = require('connect-redis');
const RedisStore = connectRedis(session)
const redisClient = redis.createClient({
host: 'localhost',
port: 6379
})
redisClient.on('error', function (err) {
console.log('Could not establish a connection with redis. ' + err);
});
redisClient.on('connect', function (err) {
console.log('Connected to redis successfully');
});
app.use(session({
store: new RedisStore({ client: redisClient }),
secret: 'secret$%^134',
resave: false,
saveUninitialized: false,
cookie: {
secure: false, // if true only transmit cookie over https
httpOnly: false, // if true prevent client side JS from reading the cookie
maxAge: 1000 * 60 * 10 // session max age in miliseconds
}
}))
app.use(
session({
name: 'AuthCookie',
secret: 'some secret string!',
resave: false,
saveUninitialized: true
})
);
app.listen(port, () => {
console.log("We've now got a server!");
console.log('Your routes will be running on http://localhost:3000');
});
I read that I should add await client.connect() but I am not sure

Apollo client not connecting to server when Redis cookie is set

When I try to login which sets a cookie and then I refresh the page I don't get any response from apollo server and every requests made by graphql client are kept (pending) status.
After I remove a cookie, everything seems to work fine. I'm not even sure how can I debug this and have a little experience with backend so any advice would be helpful.
Here is how I setup connection from client:
const link = createHttpLink({
uri: 'http://localhost:5000/graphql',
credentials: 'include',
});
const apolloLink = ApolloLink.from([
errorLink,
link
]);
const apolloClient = new ApolloClient({
cache: new InMemoryCache(),
link: apolloLink,
});
And server:
useContainer(Container);
const establishDatabaseConnection = async (): Promise<void> => {
try {
await createDatabaseConnection();
} catch (error) {
console.error(error);
}
};
const initExpressGraphql = async () => {
const app = express();
const redis = new Redis();
const RedisStore = connectRedis(session);
const corsOptions = {
origin: 'http://localhost:3000',
credentials: true,
};
const schema = await buildSchema({
resolvers: RESOLVERS,
container: Container,
});
const apolloServer = new ApolloServer({
schema: schema as GraphQLSchema,
context: ({ req, res }: any) => ({ req, res }),
introspection: true,
plugins: [
ApolloServerLoaderPlugin({
typeormGetConnection: getConnection, // for use with TypeORM
}),
],
});
app.use(
session({
store: new RedisStore({
client: redis as any,
}),
name: 'rds',
secret: 'verysecretdata',
resave: false,
saveUninitialized: false,
cookie: {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
maxAge: 1000 * 60 * 60 * 24 * 7 * 365, // 7 years
sameSite: 'lax',
},
})
);
apolloServer.applyMiddleware({
app,
cors: corsOptions
})
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Server started on port ${PORT}`));
};
const startServer = async (): Promise<void> => {
await establishDatabaseConnection();
initExpressGraphql();
};
startServer();
My issue got solved after I restarted redis server

set up mssql-session-store in node.js

I'm trying to use mssql-session-store as nodejs (express) store for session:
https://www.npmjs.com/package/mssql-session-store
This is how it should be configured(from npm page):
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: false,
store: new MssqlStore(options) // see options below
}));
var options = {
connection: existingConnection,
ttl: 3600,
reapInterval: 3600,
reapCallback: function() { console.log('expired sessions were removed);
}
};
My problem is with the options.connection. It should be "Optional instance of a Connection from mssql".
This connection establishment is an async process (from the npm page):
const sql = require('mssql')
async () => {
try {
await sql.connect('mssql://username:password#localhost/database')
const result = await sql.query`select * from mytable where id =
${value}`
console.dir(result)
} catch (err) {
// ... error checks
}
}
This is how express session is being defined in the nodejs initialization:
app.use(session({
name:<session name>,
key: <session key id>,
resave:false,
saveUninitialized:false,
secure: process.env.NODE_ENV ==="production",
secret:<secret string>,
store: new MssqlStore(options), //This is optional - for use when using sql server as a store
cookie:{
//httpOnly: true,
secure: process.env.NODE_ENV ==="production",
expires: config.expressSession.cookieLifeTime
}
}));
The problem is that establishment of the connection is an async process. I've tried several versions to both use the express-session in the application, but doing so just after the connection has been set up (async).
See my basic code (initialization of node.js - servre.js file):
const express = require('express');
const app = express();
const sql = require('mssql');
const session = require ('express-session');
const MssqlStore = require ('mssql-session-store')(session);
var sqlStore = null;
var store = null;
var mssqlConfig =
{
user: <user>
password: <password>,
server: <server name>
database: <database>,
options: {
encrypt: true // Use this if you're on Windows Azure
}
}
I've tried setting the session in the app in the connetion promise:
var sqlConnection = null;
async function getConnectedConnectionOptions()
{
try
{
sqlConnection = await sql.connect(<connection string>);
return await Promise.resolve(sqlconnection: sqlConnection);
} catch (err)
{
sqlConnection = null;
}
}
getConnectedConnectionOptions(),then(result =>
app.use(session({
name:<session name>,
key: <session key id>,
resave:false,
saveUninitialized:false,
secure: process.env.NODE_ENV ==="production",
secret:<secret string>,
store: new MssqlStore(result) ,
cookie:{
//httpOnly: true,
secure: process.env.NODE_ENV ==="production",
expires: config.expressSession.cookieLifeTime
}
}));
but then there's a scope problem where session is not defined in the global app.
Please support.
this is inside example folder in the mssql-session-store module
var dbConfig = {
server: "localhost\\sqlexpress",
database: "sessiontest",
user: "sa",
password: "atonan"
};
var start = function(callback) {
callback = callback || function() {};
sql.connect(dbConfig, function(err) {
if (err) return callback(err);
var app = express();
app.use(session({
secret: '991E6B44882C4593A46C0DDFCA23E06A',
resave: false,
saveUninitialized: false,
store: new MssqlStore({ reapInterval: 10, ttl: 10 })
}));

Resources