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
Related
When on localhost this works, in production this error is triggered Unauthorized
Production is running on Digital Ocean App Platform
Nodejs
require("dotenv").config();
require("./lib/mongodb");
const express = require("express");
const socket = require("socket.io");
const logger = require("morgan");
const cors = require("cors");
const session = require("express-session");
const MongoStore = require("connect-mongo");
const chatSocket = require("./sockets/chat");
const passport = require("./routes/passport");
const sessionMiddleware = session({
resave: false,
saveUninitialized: false,
secret: process.env.MONGO_SECRET,
store: MongoStore.create({
mongoUrl: process.env.MONGO_URI,
ttl: 12 * 60 * 60,
}),
cookie: {
secure: process.env.NODE_ENV === "production",
domain: process.env.FRONTEND_URL,
path: "/",
httpOnly: true,
maxAge: 14 * 24 * 60 * 60 * 1000,
},
});
const app = express()
.use(sessionMiddleware)
.use(passport.initialize())
.use(passport.session())
.use(logger("dev"))
.use(
express.json({
verify: function (req, res, buf) {
var url = req.originalUrl;
if (url.startsWith("/webhooks/checkout/stripe")) {
req.rawBody = buf.toString();
}
},
})
)
.use(express.urlencoded({ extended: false }))
.use(cors())
.use("/api", require("./routes"))
.use("/webhooks", require("./webhooks"))
.listen(process.env.PORT || 8080);
const io = socket(app, {
cors: {
origin: process.env.FRONTEND_URL,
methods: ["GET", "POST"],
credentials: true,
},
});
const wrap = (middleware) => (socket, next) => {
return middleware(socket.request, {}, next);
};
io.use(wrap(sessionMiddleware));
io.use(wrap(passport.initialize()));
io.use(wrap(passport.session()));
io.use((socket, next) => {
if (socket.request.user) {
next();
} else {
next(new Error("Unauthorized"));
}
});
io.on("connection", (socket) => chatSocket(io, socket));
Nextjs/Reactjs
useEffect(() => {
if (socket === null && user) {
const socket = io("https://api.websidev.com", {
withCredentials: true,
transports: ["websocket", "polling", "flashsocket"],
});
setSocket(socket);
}
}, [socket, selected, project, user, messagesRef]);
I'm storing cookies on my server, but when I tried to access them. Object Returns Null.
code I'm using to store my cookies. This is done when I'm logging in!
res.cookie("accessToken", accessToken, {
httpOnly: true,
secure: true,
expires: new Date(Date.now() + oneDay),
});
res.cookie("refreshToken", refreshToken, {
httpOnly: true,
secure: true,
expires: new Date(Date.now() + oneDay),
});
index.ts
const dotenv = require("dotenv");
dotenv.config();
const PORT = process.env.PORT || 3001;
const cookies = require("cookie-parser");
const express = require("express");
const app = express();
const cors = require("cors");
app.use(cors());
app.use(express.json());
app.use(cookies());
import dbConnect from "./db/connect";
import adminAuthRoter from "./routes/admin/adminAuthRouter";
app.get("/", (req: any, res: any) => {
res.send("Hello World");
});
app.use("/api/v1/adminauth", adminAuthRoter);
const start = async () => {
try {
await dbConnect(process.env.MONGODB_URI);
app.listen(PORT, () =>
console.log(`Server is listening on port ${PORT}...`)
);
} catch (error) {
console.log(error);
}
};
start();
When I tried to console.log(req.cookies) or console.log(req.signedCookies) my response is empty. But when I see my Postmon cookies there are cookies stored
Postmon Cookie Reponse Image
What may be the issue here?
Whenever I set the "Include Cookies" option as "On", the graphql server says that the server is not responding.
This works fine if the option is "Off".
Here is the index.ts
const main = async () => {
const mikroOrmConfig = {
debug: true,
user: 'postgres',
entities: [Post, User],
type: 'postgresql',
dbName: 'lireddit',
password: 'graphql',
allowGlobalContext: true,
migrations: {
path: path.join(__dirname, './migrations'),
pattern: /^[\w-]+\d+\.[tj]s$/
}
} as Parameters<typeof MikroORM.init>[0];
const orm = await MikroORM.init(mikroOrmConfig);
const app = express();
app.use(cors())
const apolloServer = new ApolloServer({
schema: await buildSchema({
resolvers: [PostResolver, UserResolver],
validate: false
}),
context: ({ req, res }): MyContext => ({ em: orm.em, req, res })
});
await apolloServer.start();
apolloServer.applyMiddleware({ app })
app.listen(4000, () => {
console.log("Server started at port 4000")
})
};
main().catch(err => console.error(err));
I get the following error if I try to hit an API:
{
"name": "TypeError",
"message": "Failed to fetch",
}
Update:
Setting this to the server worked:
app.set('trust proxy', true)
app.use(
cors({
credentials: true,
origin: [
"https://studio.apollographql.com",
"http://localhost:4000/graphql",
],
})
);
Also, needed to attach this header in the request:
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));
I am trying to setup graphql with passport.js, everything seems to work fine on the server side, but on the client side when I do a check to see which user is currently logged in (req.user) I get undefined, while in server side, I do get the current user
I am running my server on localhost:4000 and client on localhost:3000.
some of my configs are as follows:
I have tried to change credentials on the client side as well as cors on the server side
Server config
app.use(
session({
resave: false,
saveUninitialized: false,
secret,
store: new MongoStore({
url: MONGO_URI,
autoReconnect: true
}),
cookie: {
maxAge: 1000 * 60 * 60 * 2
}
})
);
const server = new ApolloServer({
typeDefs,
resolvers,
// required for passport req.user access
playground: { settings: { 'request.credentials': 'include' } },
// so we have access to app req,res through graphql
context: ({ req, res }) => ({
req,
res
})
});
server.applyMiddleware({ app });
Client Config
const cache = new InMemoryCache();
const link = new HttpLink({
uri: 'http://localhost:4000/graphql',
credentials: 'same-origin',
});
const client = new ApolloClient({
cache,
link,
});
I am hoping to be able to access get the current logged in user on the client side (react)
Just in case anyone has the same issue, there are a couple of things we need to fix in order to make this work:
in client:
const link = createHttpLink({
uri: 'http://localhost:4000/graphql',
credentials: 'include',
});
in Server:
// pass types and resolvers
const server = new ApolloServer({
typeDefs,
resolvers,
// required for passport req.user access
playground: { settings: { 'request.credentials': 'include' } },
// so we have access to app req,res through graphql
context: ({ req, res }) => ({
req,
res
})
});
server.applyMiddleware({
app,
cors: { origin: 'http://localhost:3000', credentials: true }
});
It worked for me :)