React Apollo曾经用userID设置cookie



我想做的是:

  1. 创建登录突变并使用它返回用户id和用户名
  2. 向具有用户id的浏览器(chrome(添加cookie,以检查用户是否登录

如果我不将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;
}

根据您当前的代码,您只在一个地方使用req.session!.userId,并且您使用时出现错误。这让我觉得你对redis有意见。

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

在启动应用程序之前,请先启动redis服务器。

最新更新