apollo-graphql不在浏览器上存储cookie



我有一个关于饼干的问题。在这里,我使用apollo-server-express、express-session和redis进行所有身份验证过程。我的问题是,在阿波罗工作室我的cookie,这是在UserResolver下的突变登录中创建的,没有显示在那里。这就是为什么查询me返回null。还值得一提的是,我在做所有这些时没有得到任何错误。

为了更好地理解,我将在下面留下一些截图。

我希望有人能帮我解决这个问题。提前谢谢。

索引。ts(服务器设置)

import {MikroORM} from "@mikro-orm/core";
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";
const { createClient } = require("redis")
import session from "express-session";
import connectRedis from "connect-redis";
import {__prod__} from "./constants";
import {MyContext} from "./types";
const main=async () => {
const orm=await MikroORM.init(microConfig)
await  orm.getMigrator().up()
const app=express();
const RedisStore = connectRedis(session);
const redisClient = createClient({
legacyMode: true
});
redisClient.connect().catch(console.error)
app.set('trust proxy', !__prod__)
app.use(
session({
name: "qid",
store: new RedisStore({
client: redisClient,
disableTouch: true,
}),
cookie: {
maxAge: 1000 * 60 * 60 * 24 * 365 * 10, // 10 years
httpOnly: true,
sameSite: "none", // csrf
secure: __prod__, // cookie only works in https
},
saveUninitialized: false,
secret: "qowiueojwojfalksdjoqiwueo",
resave: false,
})
);
const apolloServer =new ApolloServer({
schema:await buildSchema({
resolvers:[HelloResolver,PostResolver,UserResolver],
validate:false
}),
context:({req,res}):MyContext => ({em:orm.em,req,res})
})
await apolloServer.start();
const corsOptions={origin:["https://studio.apollographql.com", "http://localhost:4000"],credentials:true}
apolloServer.applyMiddleware({app,cors:corsOptions})
app.listen(4000,()=>{
console.log("server listening on port 4000")
})
}
main()

用户。ts(我的解析器)

import {
Resolver,
Mutation,
Arg,
InputType,
Field,
Ctx,
ObjectType,
} from "type-graphql";
import { MyContext } from "../types";
import { User } from "../entities/User";
import argon2 from "argon2";
@InputType()
class UsernamePasswordInput {
@Field()
username: string;
@Field()
password: string;
}
@ObjectType()
class FieldError {
@Field()
field: string;
@Field()
message: string;
}
@ObjectType()
class UserResponse {
@Field(() => [FieldError], { nullable: true })
errors?: FieldError[];
@Field(() => User, { nullable: true })
user?: User;
}
@Resolver()
export class UserResolver {
@Mutation(() => UserResponse)
async register(
@Arg("options") options: UsernamePasswordInput,
@Ctx() { em }: MyContext
): Promise<UserResponse> {
if (options.username.length <= 2) {
return {
errors: [
{
field: "username",
message: "length must be greater than 2",
},
],
};
}
if (options.password.length <= 2) {
return {
errors: [
{
field: "password",
message: "length must be greater than 2",
},
],
};
}
const hashedPassword = await argon2.hash(options.password);
const user = em.create(User, {
username: options.username,
password: hashedPassword,
});
try {
await em.persistAndFlush(user);
} catch (err) {
//|| err.detail.includes("already exists")) {
// duplicate username error
if (err.code === "23505") {
return {
errors: [
{
field: "username",
message: "username already taken",
},
],
};
}
}
return { user };
}
@Mutation(() => UserResponse)
async login(
@Arg("options") options: UsernamePasswordInput,
@Ctx() { em,req }: MyContext
): Promise<UserResponse> {
const user = await em.findOne(User, { username: options.username });
if (!user) {
return {
errors: [
{
field: "username",
message: "that username doesn't exist",
},
],
};
}
const valid = await argon2.verify(user.password, options.password);
if (!valid) {
return {
errors: [
{
field: "password",
message: "incorrect password",
},
],
};
}
req.session.userId = user.id;

return {
user,
};
}
}

首先,您必须在index.ts

中添加两行
app.set("Access-Control-Allow-Origin", "https://studio.apollographql.com");
app.set("Access-Control-Allow-Credentials", true);

配置Apollo graphql studio->转到连接设置->编辑→包括饼干确保添加这个标题:x-forward -proto: https

我已经将安全密钥更改为true并且它有效

cookie: {
maxAge: 1000 * 60 * 60 * 24 * 365 * 10, // 10 years
httpOnly: true,
sameSite: "none", // csrf
secure: true, // changed to true from __prod_ 
},

我查看了他们的文档,他们建议使用阿波罗4+下面的设置可能会帮助您将端点设置为http://localhost:4000/graphql而不是https://studio.apollographql.com/

// Apollo Recommended Plugin
let plugins: any = [];
if (process.env.NODE_ENV === "production") {
plugins = [
ApolloServerPluginLandingPageProductionDefault({
embed: true,
graphRef: "myGraph@prod",
includeCookies: true,
}),
];
} else {
plugins = [
ApolloServerPluginLandingPageLocalDefault({
embed: true,
includeCookies: true, // very important
}),
];
}

传递给new ApolloServer({})中的plugins