如何为Urql客户端设置Authorization header?

问题描述 投票:0回答:1

我有一个 NextJS 应用程序,我正在其中实现 Supabase 进行身份验证,并尝试使用 Urql 来删除 Apollo。

在我的

urql.ts
文件中,我正在创建这样的客户端:

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

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({}),
    ssrCache,
    fetchExchange,
  ],
  fetchOptions: () => {
    return {
      credentials: 'include',
      headers: { Authorization: `Bearer ${token}` }, // how to return token?
    };
  },
});

export { client, ssrCache };

我想弄清楚如何实际返回令牌?因为上下文没有传递,所以我无法从那里提取它。 Supabase 将令牌设置为 HttpOnly,所以我相信这也阻止我在这里访问它。使用 Js-Cookie 等库会返回未定义。

有没有办法将上下文传递给

fetchOptions
,或者我应该尝试找出如何在设置cookie时删除HttpOnly?

graphql next.js supabase urql
1个回答
0
投票

我正在使用 Remix 和 urql,但想法应该是一样的。

您可以使用

createBrowserClient
中的
@supabase/ssr
并在
fetchOptions

中设置令牌
import { Client, cacheExchange, fetchExchange } from "urql";

export const createUrqlClient = (accessToken?: string) => {
  const url = import.meta.env.VITE_SUPABASE_URL!
  const key = import.meta.env.VITE_SUPABASE_ANON_KEY!
  return new Client({
    url: `${url}/graphql/v1`,
    exchanges: [cacheExchange, fetchExchange],
    fetchOptions: () => {
      return {
        headers: {
          apiKey: `${key}`,
          authorization: `Bearer ${accessToken || key}`,
        }
      };
    },
  });
}

在你的 React 组件中:

import { createBrowserClient } from "@supabase/ssr";

const Main = ({ children }: { children: React.ReactNode }) => {
  const [accessToken, setAccessToken] = useState<string|undefined>()
  const supabase = createBrowserClient(
    import.meta.env.VITE_SUPABASE_URL!,
    import.meta.env.VITE_SUPABASE_ANON_KEY!,
  )
  useEffect(() => {
    supabase.auth.getSession().then(({ data: { session } }) => {
      setAccessToken(session?.access_token)
    })
  })
  const client=useMemo(() => createUrqlClient(accessToken), [accessToken]);
  return (
    <Provider value={client}>
        {children}
    </Provider>
  )
}
© www.soinside.com 2019 - 2024. All rights reserved.