Файл cookie не устанавливается в браузере, даже если запись создана в базе данных — GraphQL, ApolloServer, MongoDB, Express

#express #graphql #session-cookies #apollo-server

Вопрос:

Я создаю проект и хочу хранить данные сеанса в MongoDB с помощью ApolloServer, Express, GraphQL, однако я не могу установить файлы cookie в браузере (Chrome и Firefox). Изначально у меня было несколько ошибок CORS, я считаю, что исправил их. Данные сеанса и идентификатор успешно хранятся в MongoDB, Когда я вхожу в систему и запускаю запрос «я», чтобы проверить, был ли установлен файл cookie, он возвращает значение null, так как ничего не было установлено, Пожалуйста, помогите мне

index.js

 import "reflect-metadata";
import { MikroORM } from "@mikro-orm/core";
import { ApolloServer } from "apollo-server-express";
import express from "express";
import { buildSchema } from "type-graphql";
import mikroOrmConfig from "./mikro-orm.config";
import { HelloResolver } from "./resolvers/hello";
import { PostResolver } from "./resolvers/post";
import { UserResolver } from "./resolvers/user";
import session from "express-session";
import MongoStore from "connect-mongo";
import { __prod__ } from "./constants";
import { MyContext } from "./types";


const main = async () => {
  const orm = await MikroORM.init(mikroOrmConfig);
  await orm.getMigrator().up();

  const app = express();

  const corsOptions = {
    origin: 'https://studio.apollographql.com',
    credentials: true
  }

  app.set("trust proxy", 1);
  

  app.use(
    session({
      name: "qid",
      secret: "secret",
      saveUninitialized: false,
      resave: false,
      store: MongoStore.create({
        mongoUrl: "mongodb://localhost/test-app",
        touchAfter: 24 * 3600, // time period in seconds
      }),
      cookie: {
          maxAge: 3600 * 60 *30 * 24 * 3600,
          secure: true,
          httpOnly: true,
          sameSite: 'lax'
      }
    })
  );

  const apolloServer = new ApolloServer({
    schema: await buildSchema({
      resolvers: [HelloResolver, PostResolver, UserResolver],
      validate: false,
    }),
 
    context: ({ req, res }): MyContext => ({ em: orm.em.fork(), req, res }),
  });

  await apolloServer.start();
  apolloServer.applyMiddleware({ app, cors: corsOptions });

  app.listen(4000, () => {
    console.log("server started on port 4000");
  });
};

 

пакет.json

  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@types/connect-mongo": "^3.1.3",
    "@types/express": "^4.17.13",
    "@types/express-session": "^1.17.4",
    "@types/mongodb": "^4.0.7",
    "@types/node": "^16.7.2",
    "express-session": "^1.17.2",
    "nodemon": "^2.0.12",
    "ts-node": "^10.2.1",
    "typescript": "^4.3.5"
  },
  "dependencies": {
    "@mikro-orm/cli": "^4.5.9",
    "@mikro-orm/core": "^4.5.9",
    "@mikro-orm/migrations": "^4.5.9",
    "@mikro-orm/postgresql": "^4.5.9",
    "apollo-server-express": "^3.3.0",
    "argon2": "^0.28.2",
    "connect-mongo": "^4.5.0",
    "express": "^4.17.1",
    "graphql": "^15.5.1",
    "pg": "^8.7.1",
    "reflect-metadata": "^0.1.13",
    "type-graphql": "^1.1.1"
  },
  "mikro-orm": {
    "configPaths": [
      "./sr/mikro-orm.config.ts",
      "./dist/mikro-orm.config.js"
    ]
  }
 

user.ts login Mutation

 @Mutation(() => UserResponse)
  async login(
    @Arg("options", () => UsernamePasswordInput) options: UsernamePasswordInput,
    @Ctx() { em, req }: MyContext
  ): Promise<UserResponse> {
    const user = await em.findOne(User, { username: options.username });
    if (!user) {
      return {
        errors: [
          {
            field: "username",
            message: "Invalid Username",
          },
        ],
      };
    }

    const valid = await argon2.verify(user.password, options.password);

    if (!valid) {
      return {
        errors: [
          {
            field: "password",
            message: "Invalid Password",
          },
        ],
      };
    }

    req.session.userId = user.id;

    return {
      user,
    };
  }
 

Запрос user.ts me

 @Query(() => User, {nullable: true})
    async me(
      @Ctx() { req, em }: MyContext,
    ){
      if(!req.session.userId){
        return null;
      }
      else {
        const user = await em.findOne(User, { id: req.session.userId });
        return user;
      }
    }
 

Контекст

 import { EntityManager, IDatabaseDriver, Connection } from "@mikro-orm/core";
import { Request, Response } from "express";
import { Session } from 'express-session';

export interface MyContext {
    em: EntityManager<any> amp; EntityManager<IDatabaseDriver<Connection>>;
    req: Request amp; { session?: Session amp; { userId?: number }};
    res: Response;
};

 

Данные сеанса сохраняются в MongoDB

ApolloGraphQL, пользователь равен нулю даже после входа в систему

Пожалуйста, помогите мне или дайте мне несколько советов, если я допустил какие-либо ошибки, спасибо!

Комментарии:

1. Вы устанавливаете файл cookie на сервере и пытаетесь получить к нему доступ в браузере, верно?

2. @Ammar Да, при входе в систему создается файл cookie, который отображается в базе данных, но когда я запрашиваю его в браузере, он, похоже, исчез

3. Вы не можете получить доступ к файлам cookie HttpOnly внутри браузера. Пожалуйста, попробуйте передать HttpOnly: false внутри вашего объекта cookie. Кроме того, проверьте это, вручную проверив файл cookie в вашем браузере.

4. @Ammar Запрос me по-прежнему выводит значение null даже после входа в систему 🙁