You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apollo Server v4如何抛出错误?迁移后GraphQLError报错问题咨询

Apollo Server V3 迁移至 V4:登录Resolver适配方案

核心适配要点与完整代码示例

1. 上下文(Context)传递适配

V4中上下文的创建逻辑有所调整,需确保res(响应对象)和prisma能正确注入到Resolver:

// V4 上下文配置示例(Express环境)
import { ApolloServer } from '@apollo/server';
import { expressMiddleware } from '@apollo/server/express4';
import express from 'express';
import { yourPrismaInstance } from './prisma-client';

const app = express();
const server = new ApolloServer<ProjectContext>({ typeDefs, resolvers });

await server.start();

app.use(
  '/graphql',
  express.json(),
  expressMiddleware(server, {
    context: async ({ req, res }) => ({ prisma: yourPrismaInstance, res }),
  }),
);

2. 补全并适配后的登录Resolver

以下是完善后的登录校验逻辑,适配V4的错误处理与Cookie设置规范:

import { Mutation, Arg, Ctx } from '@nestjs/graphql'; // 若使用NestJS;纯Apollo则对应导入@apollo/server装饰器
import { GraphQLError } from 'graphql';
import { verify } from 'argon2'; // 假设使用argon2做密码哈希校验
import jwt from 'jsonwebtoken';
import { ProjectContext } from './your-context-types';
import { AccessToken } from './your-gql-types';

export class LoginResolver {
    @Mutation(() => AccessToken)
    async login(
        @Arg("email") email: string,
        @Arg("password") password: string,
        @Ctx() { prisma, res }: ProjectContext
    ): Promise<AccessToken> {
        // 校验用户存在性
        const user = await prisma.user.findFirst({ where: { email } });
        if (!user) {
            throw new GraphQLError("未找到用户", {
                extensions: { code: 'USER_NOT_FOUND' } // V4推荐添加标准化错误码
            });
        }

        // 校验密码合法性
        const valid = await verify(user.password, password);
        if (!valid) {
            throw new GraphQLError("密码无效", {
                extensions: { code: 'INVALID_PASSWORD' }
            });
        }

        // 生成JWT AccessToken
        const accessToken = jwt.sign(
            { userId: user.id, email: user.email },
            process.env.JWT_SECRET!,
            { expiresIn: '1h' }
        );

        // 设置HttpOnly安全Cookie
        res.cookie('accessToken', accessToken, {
            httpOnly: true,
            secure: process.env.NODE_ENV === 'production',
            sameSite: 'strict',
            maxAge: 3600000 // 有效期1小时
        });

        return { token: accessToken };
    }
}

3. 迁移关键注意事项

  • 错误处理优化:V4建议为GraphQLError添加extensions.code字段,便于前端统一处理错误类型
  • 依赖切换:移除V3的apollo-server-express依赖,改用@apollo/server + @apollo/server/express4组合
  • 装饰器兼容:若使用代码优先的Schema生成(如NestJS GraphQL),原有@Mutation/@Arg等装饰器无需修改;纯Apollo场景需确保导入@apollo/server提供的装饰器
  • Cookie安全:生产环境必须开启secure: true,确保Cookie仅通过HTTPS传输

内容的提问来源于stack exchange,提问作者Vishvaa Kesav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 18:15:42