尝试设置 cookie 时 apollo 4.0 express redis 应用程序中未定义的会话对象

问题描述 投票:0回答:0

对于我的全栈应用程序的后端,我使用 ApolloGraphQL 4.0 和 Express。我可以成功地使用我的解析器(TypeOrm 和 TypeGraphql)从我的数据库(PostgreSQL)写入和检索数据。 我将 express-session 与 connect-redis 包一起使用来处理会话并为我的注册解析器设置一个 cookie,但是当尝试将数据存储在会话对象中时,我收到以下关于我的会话对象的错误消息:

TypeError: Cannot read properties of undefined (reading 'session')
并且没有设置cookie。

我试过不同版本的 connect-redis 包,我试过更改不同中间件的顺序等等,但无论我做什么,我都会得到同样的错误,并且没有设置 cookie。 这是我的 index.ts:

import "reflect-metadata";
import AppDataSource from "./data-source";
import { ApolloServer } from "@apollo/server";
import { expressMiddleware } from "@apollo/server/express4";
import { ApolloServerPluginDrainHttpServer } from "@apollo/server/plugin/drainHttpServer";
import express, { Request, Response } from "express";
import http from "http";
import cors from "cors";
import { json } from "body-parser";
import { Hello } from "./resolvers/hello";
import { UserResolver } from "./resolvers/user";
import { buildSchema } from "type-graphql";
import RedisStore from "connect-redis";
import session from "express-session";
import { createClient } from "redis";

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

const main = async () => {
  await AppDataSource.initialize();

  const app = express();

  app.set("trust proxy", 1);
  app.set(
    "Access-Control-Allow-Origin",
    "https://sandbox.embed.apollographql.com"
  );
  app.set("Access-Control-Allow-Credentials", true);

  const httpServer = http.createServer(app);
  const port = 3000;
  const corsOptions = {
    origin: "https://sandbox.embed.apollographql.com",
    credentials: true,
  };

  const redisClient = createClient();
  redisClient.connect().catch(console.error);
  const redisStore = new RedisStore({
    client: redisClient,
    prefix: "myapp:",
  });

  const apolloServer = new ApolloServer({
    schema: await buildSchema({
      resolvers: [Hello, UserResolver],
    }),
    plugins: [ApolloServerPluginDrainHttpServer({ httpServer })],
  });

  await apolloServer.start();

  app.use(
    session({
      name: "qid",
      store: redisStore,
      resave: false,
      saveUninitialized: false,
      secret: "weotjweptoijwepitn",
      cookie: {
        maxAge: 1000 * 60 * 60 * 24 * 365 * 10,
        httpOnly: true,
        sameSite: "none",
        secure: true,
      },
    }),
    cors(corsOptions),
    json(),
    expressMiddleware(apolloServer, {
      context: async ({ req, res }) => ({ req, res }),
    })
  );

  httpServer.listen(port, () => {
    console.log(`Server now running on port: ${port}`);
  });
};

main();

这就是我的 userResolver 在注册后让用户保持登录状态的样子:

import { Resolver, Mutation, Arg, Query, Ctx } from "type-graphql";
import User from "../entities/User";
import { MyContext } from "../index";

@Resolver()
export class UserResolver {
  @Mutation(() => User)
  async register(
    @Arg("username") username: string,
    @Arg("password") password: string,
    @Arg("email") email: string,
    @Ctx("req") { req }: MyContext,
  ): Promise<User> {
    const user = await User.create({
      username,
      email,
      password,
    }).save();

    try {
      req.session.userId = user.id;
    }
    catch (error) {
      console.log(error);
      console.error(error);
    }

    return user;
  }

  @Query(() => [User])
  async findAllUsers(): Promise<User[]> {
    const Users = await User.find({
      select: {
        id: true,
        username: true,
        email: true,
      },
    });
    return Users;
  }
}

express session cookies redis apollo
© www.soinside.com 2019 - 2024. All rights reserved.