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

NextJS搭配Supabase鉴权时如何为Urql客户端设置Authorization请求头

解决方案

首先明确:绝对不要移除Cookie的HttpOnly属性,这是防范XSS攻击窃取用户身份凭证的核心安全机制,移除会带来严重的安全风险。
你遇到的问题可以分客户端请求、服务端请求两种场景分别处理,不需要手动读取HttpOnly Cookie:

1. 客户端侧请求处理

你已经在配置里加了credentials: 'include',浏览器发起请求时会自动携带所有同域的HttpOnly Cookie,你的GraphQL后端可以直接从请求的Cookie字段中读取Supabase的身份凭证,无需你手动在前端把token塞入Authorization头。
如果你的后端确实要求必须从Authorization头获取token,可以使用Urql官方的@urql/exchange-auth交换器,配合Supabase客户端获取token:
首先安装依赖:

npm install @urql/exchange-auth

然后修改urql.ts的配置:

import { createClient, ssrExchange, dedupExchange, fetchExchange } from 'urql';
import { cacheExchange } from '@urql/exchange-graphcache';
import { devtoolsExchange } from '@urql/devtools';
import { authExchange } from '@urql/exchange-auth';
// 引入你项目里初始化好的Supabase客户端
import { supabase } from './supabase';

const isServerSide = typeof window === 'undefined';
const ssrCache = ssrExchange({
  isClient: !isServerSide,
  initialState: !isServerSide ? window.__URQL_DATA__ : undefined,
});

const client = createClient({
  url: '/api/graphql',
  exchanges: [
    devtoolsExchange,
    dedupExchange,
    cacheExchange({}),
    authExchange(async utils => {
      // 客户端侧通过Supabase客户端获取session
      const { data: { session } } = await supabase.auth.getSession();
      return {
        addAuthToOperation(operation) {
          if (!session?.access_token) return operation;
          return utils.appendHeaders(operation, {
            Authorization: `Bearer ${session.access_token}`,
          });
        },
        willAuthError() { return false },
        didAuthError() { return false },
        async refreshAuth() {},
      };
    }),
    ssrCache,
    fetchExchange,
  ],
  fetchOptions: () => {
    return {
      credentials: 'include',
    };
  },
});

export { client, ssrCache };

2. 服务端侧请求处理

在NextJS服务端渲染场景(Pages Router的getServerSideProps、App Router的服务端组件),你需要从传入的请求头中提取Cookie,再初始化对应请求的Urql客户端实例,直接透传Cookie给后端即可:
以Pages Router的getServerSideProps为例:

import { createClient, ssrExchange, dedupExchange, fetchExchange } from 'urql';
import { cacheExchange } from '@urql/exchange-graphcache';
import { parse } from 'cookie';

export async function getServerSideProps(context) {
  const ssrCache = ssrExchange({ isClient: false });
  
  const serverClient = createClient({
    url: '/api/graphql',
    exchanges: [dedupExchange, cacheExchange({}), ssrCache, fetchExchange],
    fetchOptions: {
      credentials: 'include',
      headers: {
        // 直接把客户端传来的Cookie透传给后端即可,不需要解析token
        Cookie: context.req.headers.cookie || '',
      },
    },
  });
  
  // 这里执行服务端的GraphQL查询逻辑...
  
  return {
    props: {
      urqlState: ssrCache.extractData(),
    },
  };
}

内容的提问来源于stack exchange,提问作者J. Jackson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 07:06:03