【问题标题】:React Apollo used to set a cookie with userIDReact Apollo 用于设置带有 userID 的 cookie
【发布时间】:2022-02-01 14:57:18
【问题描述】:

我想做的是:

  1. 创建登录突变并使用它返回用户 ID 和用户名
  2. 将 cookie 添加到带有用户 ID 的浏览器 (chrome) 以检查用户是否已登录

如果我不将 userId 分配给会话,则登录突变有效,有效意味着它返回请求的数据。 但是,当我添加以下代码行以将 userId 添加到会话时,它会创建一个 cookie,但我无法获取数据(userId 和 userName):

req.session!.userId = user.id;

我收到无法获取数据的信息,请检查您的连接。 我不确定我什么时候犯了错误,感谢任何帮助。

下面我提供我的设置:

index.ts

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

const main = async () => {
    //console.log("dirname: ", __dirname);

    // connect db
    const orm = await MikroORM.init(microConfig);
    // run migrations
    await orm.getMigrator().up();

    const app = express();

    // importing connect redis causing issue with session object
    const RedisStore = require('connect-redis')(session)
    //const RedisStore = connectRedis(session);
    //const redisClient = redis.createClient();
    const redisClient: IORedis.Cluster = new IORedis.Cluster([])

// https://github.com/tj/connect-redis/issues/300
// installed ioredis
    app.use(
        session({
          name: "rjsession",
          store: new RedisStore({
               client: redisClient,
               disableTouch: true,
             }),
          cookie: {
                 maxAge: 1000 * 60 * 60 * 24 * 365 * 10, // 10 years
                 httpOnly: true,
                 sameSite: 'lax',
                 //secure: __prod__, //cookie works only in https, on dev good to run off
                 secure: false,
             },
          saveUninitialized: false,
          secret: 'keyboard catadasdasdsdaasdadas',
          resave: false,
        })
      )

    const apolloServer = new ApolloServer({
        schema: await buildSchema( {
            resolvers: [HelloResolver, PostResolver, UserResolver],
            validate: false,
        }),
        context: ({ req, res }): MyContext => ({ em: orm.em, req, res }),
        // added plugin to force apollo server to use old graphql playground
        plugins: [
            ApolloServerPluginLandingPageGraphQLPlayground({
                // options

            })
        ],
    });
    
    await apolloServer.start();

    
    apolloServer.applyMiddleware({ 
        app,
        cors: { credentials: true, origin: ["http://localhost:4000/"] },
     });
    
    

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

    app.get('/', (_, res) => {
        res.send("hello");
        
    })
};

// catch error and print it
main().catch(err => {
    console.log(err);
});

登录突变定义:

    @Mutation(() => UserResponse)
    async login(
        @Arg('options') options: UsernamePasswordInput,
        @Ctx() { em, req }: MyContext
    ): Promise<UserResponse> {
        // check if user registered
        const user = await em.findOne(User, { username: options.username });

        // if user null return password
        if (!user) {    
            return {
                errors: [
                    {
                        field: "username",
                        message: "User does not exist.",
                    },
                ],
            };
        }
        // validate password against user input
        const valid = await argon2.verify(user.password, options.password);

        // return error if password failed validation
        if (!valid){
            return {
                errors: [
                    {
                        field: "password",
                        message: "password incorrect.",
                    },
                ],
            };
        }

        // asign user id in cookies

        req.session!.userId = user.id;
        console.log(req.session!.userId)

        //req.session!.userId = user.id;
        // if no errors return user
        return {
            user,
        };  
    }

types.ts 文件:

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



export type MyContext = {
    em: EntityManager<any> & EntityManager<IDatabaseDriver<Connection>>
    //req: Request & {session: Express.Session} & { userId: number };
    //req: Request & {session: Session};
    req: Request; // & {session: Express.Session};
    res: Response;
}

【问题讨论】:

    标签: node.js cookies redis apollo-server express-session


    【解决方案1】:

    根据您当前的代码,您仅在一个地方使用req.session!.userId,并且您使用时遇到错误。这让我觉得你的 redis 有问题。

    当您登录时,您的服务器将生成一个存储在 Redis 存储中的会话 ID。由于您的 redis 没有在您的机器上运行,因此您无法存储它,因此您会收到错误。

    在你启动你的应用之前,先启动redis服务器。

    【讨论】:

      猜你喜欢
      • 2020-05-31
      • 2017-03-22
      • 2021-07-31
      • 2020-06-20
      • 2022-06-30
      • 2020-05-18
      • 2021-04-09
      • 1970-01-01
      • 2023-02-25
      相关资源
      最近更新 更多