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

tRPC中Cookie处理困惑:服务端发送与客户端读取问题

问题核心

你的代码存在三个关键问题:

  1. CORS 未配置允许跨域携带凭证,导致 Cookie 无法在跨域场景下传递
  2. 客户端 tRPC 客户端未开启凭证携带,无法自动发送/接收 Cookie
  3. 服务端 Cookie 设置缺少必要的安全与跨域兼容参数

服务端代码修改

1. 修复 CORS 配置

跨域环境下必须明确允许凭证携带,同时指定可信的客户端 origin(不能用 *):

// backend/index.ts
const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// 修改CORS配置
app.use(cors({
  origin: "http://localhost:3000", // 替换为你的客户端实际地址
  credentials: true, // 允许携带凭证(Cookie)
}));

app.use(cookieParser())

app.use(
  "/login/v1",
  trpcExpress.createExpressMiddleware({
    router: loginRouter,
    createContext: createLoginContext
  })
);
app.listen(PORT, () => console.log(`server is running on port ${PORT}`));

给 Cookie 添加安全、跨域兼容参数,返回任意标识成功的内容即可(Cookie 通过响应头传递,不在返回体里):

// backend/router.ts
export async function createLoginContext({req,res}: trpcExpress.CreateExpressContextOptions) {
  return {
    req,
    res
  }
}

export type LoginContext = trpc.inferAsyncReturnType<typeof createLoginContext>

export const loginRouter = trpc.router<LoginContext>()
.mutation('testCookies', {
  async resolve({ctx, input}):Promise<{ success: boolean; message: string }> {
    console.log('Received cookies:', ctx.req.cookies);
    
    // 设置Cookie并添加必要参数
    ctx.res.cookie('testCookie', 'cooookkiiieee', {
      httpOnly: true, // 防止XSS攻击,禁止前端JS读取
      secure: process.env.NODE_ENV === 'production', // 生产环境强制HTTPS传输
      sameSite: 'lax', // 兼容跨域场景,防止CSRF
      maxAge: 24 * 60 * 60 * 1000, // 有效期1天
      path: '/' // 全站可访问
    });
    
    return { success: true, message: 'Cookie已设置' };
  }
});

客户端代码修改

1. 配置 tRPC 客户端携带凭证

开启 fetch 的凭证携带选项,让浏览器自动处理 Cookie 的发送与接收:

// client/requests.ts
const createLoginRouter = () => {
  return createTRPCClient<LoginRouter>({
    url: "http://localhost:5000/login/v1",
    // 自定义fetch逻辑,开启凭证携带
    fetch: (input, init) => {
      return fetch(input, {
        ...init,
        credentials: 'include', // 关键:允许携带Cookie等凭证
      });
    },
  });
};

如果是浏览器环境,可直接用 document.cookie 或第三方库(如 universal-cookie)读取:

// client/requests.ts
import Cookies from 'universal-cookie'; // 需先安装:npm i universal-cookie

export const testCookiesRequest = async() => {
  const client = createLoginRouter();
  const cookies = new Cookies();
  
  try {
    const val = await client.mutation('testCookies');
    // 读取刚设置的Cookie
    const testCookie = cookies.get('testCookie');
    console.log('获取到的Cookie:', testCookie);
    return val;
  } catch(e) {
    throw e;
  }
};

关键注意事项

  • 客户端与服务端的 origin 必须匹配 CORS 配置中的 origin 值,否则浏览器会拦截 Cookie
  • 生产环境必须开启 secure: true,否则 Cookie 不会在 HTTPS 下传输
  • httpOnly: true 的 Cookie 无法通过前端 JS 读取,只能由浏览器自动在请求中携带,这是安全最佳实践

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 15:40:23