未认证用户场景下如何配置根级AppSync/Apollo客户端?
Hey there! Let's tackle how to integrate your react-cognito + Redux setup with AppSync instead of relying on AWS Amplify. Here's a practical, stack-aligned breakdown to get you sorted:
First, you'll need to set up your Apollo Client to pull authentication tokens directly from your Redux store (or react-cognito's Auth utilities) instead of Amplify. We'll use aws-appsync and Apollo's context linking to inject auth details into every request.
import { ApolloClient, InMemoryCache } from '@apollo/client'; import { createAppSyncLink } from 'aws-appsync'; import { setContext } from '@apollo/client/link/context'; import store from './path/to/your/redux/store'; import { Auth } from 'react-cognito'; // Create the core AppSync link const appSyncLink = createAppSyncLink({ url: 'YOUR_APPSYNC_API_ENDPOINT', region: 'YOUR_AWS_REGION', auth: { type: 'AMAZON_COGNITO_USER_POOLS', // Fetch fresh JWT token on each request (either from Redux or react-cognito) jwtToken: async () => { // Option 1: Pull from Redux store if you've stored the token there return store.getState().auth.jwtToken; // Option 2: Fetch directly via react-cognito if you prefer // const user = await Auth.currentAuthenticatedUser(); // return user.getSignInUserSession().getIdToken().getJwtToken(); } } }); // If you need to use temporary IAM credentials (for certain AppSync data sources) // Swap the auth config above with this: // auth: { // type: 'AWS_IAM', // credentials: async () => { // const { accessKeyId, secretAccessKey, sessionToken } = store.getState().auth.temporaryIAMCredentials; // return { accessKeyId, secretAccessKey, sessionToken }; // } // } // Add context to inject auth headers (optional but useful for additional checks) const authLink = setContext((_, { headers }) => { const token = store.getState().auth.jwtToken; return { headers: { ...headers, authorization: token ? `Bearer ${token}` : '' } }; }); // Final Apollo Client setup const apolloClient = new ApolloClient({ link: authLink.concat(appSyncLink), cache: new InMemoryCache() });
Since you're using Redux for state management and PrivateRoute for auth checks, the ApolloProvider needs to sit inside your Redux Provider—this ensures it can access the latest auth state from the store. Here's how to structure your root component:
import React from 'react'; import { Provider } from 'react-redux'; import { ApolloProvider } from '@apollo/client'; import store from './path/to/your/redux/store'; import apolloClient from './path/to/your/apolloClient'; import AppRouter from './path/to/your/router'; // Contains your PrivateRoute setup const App = () => { return ( <Provider store={store}> <ApolloProvider client={apolloClient}> <AppRouter /> </ApolloProvider> </Provider> ); }; export default App;
Make sure your AppSync client reacts when users log in or out. A couple of key steps here:
- When your Redux auth reducer updates (e.g., on login/logout), the token-fetching function in your AppSync link will automatically pull the latest value on the next request—no need to reinitialize the client manually.
- If you're using temporary IAM credentials, ensure react-cognito's auto-refresh is wired up to update your Redux store when credentials rotate.
- Use your browser's dev tools to check AppSync request headers—confirm the
Authorizationheader includes your JWT token or IAM credentials. - Test your PrivateRoute flow: unauthenticated users should be blocked, and logged-in users should be able to run AppSync queries/mutations without auth errors.
- Verify logout behavior: after signing out, subsequent AppSync requests should fail (as expected) until the user logs back in.
A quick pro tip: Use the Apollo DevTools browser extension to inspect request details and confirm auth headers are being sent correctly.
内容的提问来源于stack exchange,提问作者davegravy

