如何用apollo-link-state存储的JWT实现Apollo远程查询鉴权
@client) into Remote Request Headers Got it, let's work through this. You've got your auth token stored in Apollo's local state (fetchable via query ClientToken() { clientToken @client }), and you need to attach it to the Authorization header for remote GraphQL calls. The fixed-token auth link you had works for static values, but we need to adapt it to fetch the token asynchronously from the local state.
Here's the Working Implementation
First, we'll use setContext from @apollo/client/link/context (it's cleaner for handling async context updates) to fetch the token from the client's local state before each request:
import { ApolloClient, InMemoryCache, HttpLink } from '@apollo/client'; import { setContext } from '@apollo/client/link/context'; import { gql } from '@apollo/client'; // 1. Create your HTTP link to the remote API const httpLink = new HttpLink({ uri: 'https://your-remote-graphql-api.com/graphql' }); // 2. Create the auth link that fetches the token from local state const authLink = setContext(async (_, { client }) => { // Fetch the token from the @client query const { data } = await client.query({ query: gql` query GetClientToken { clientToken @client } ` }); // Return the headers with Authorization (if token exists) return { headers: { Authorization: data.clientToken ? `Bearer ${data.clientToken}` : '' } }; }); // 3. Combine the links and initialize the Apollo Client const client = new ApolloClient({ link: authLink.concat(httpLink), cache: new InMemoryCache(), // Add your local state configuration here (if not already set up) });
Key Details to Note
- Async Token Fetch: The
setContextfunction supports async operations, so we can safely await theclient.querycall to get the latest token from local state. - Accessing the Client: The second parameter in
setContextgives us direct access to the Apollo Client instance, which we use to run the@clientquery. - Fallback for Missing Token: We check if
clientTokenexists before setting the Authorization header to avoid sending an emptyBearerstring.
Optional: Add Error Handling
If you want to handle cases where the token query fails (e.g., local state isn't initialized), wrap the query in a try/catch block:
const authLink = setContext(async (_, { client }) => { try { const { data } = await client.query({ query: gql` query GetClientToken { clientToken @client } ` }); return { headers: { Authorization: data.clientToken ? `Bearer ${data.clientToken}` : '' } }; } catch (err) { // Fallback to empty headers if token fetch fails return { headers: {} }; } });
Why Your Original Code Didn't Work
Your initial auth link used a static token (GETMEATOKEN) which is set synchronously. Since fetching from @client is an async operation, we need to wait for that token to be retrieved before setting the request headers—this implementation handles that async flow properly.
内容的提问来源于stack exchange,提问作者choise

