Redux+Axios处理API请求最佳实践:区分公开与授权请求
Hey there! Sounds like you’re fed up with repeating the same auth logic across all your authorized API calls—who wouldn’t be? Let’s break down the two solid solutions to clean this up, starting with the most widely used approach: Axios Interceptors, then a custom API wrapper for more flexible control.
1. Axios Interceptors (The Global, Set-it-and-Forget-it Solution)
This is my go-to for scenarios like yours because it centralizes all auth logic, so you never have to duplicate code in every request. Here’s how to implement it step by step:
Step 1: Create Dedicated Axios Instances
First, make separate instances for public and authorized requests—this keeps your logic clean and avoids applying auth rules to requests that don’t need them.
import axios from 'axios'; import { store } from './redux/store'; // Import your Redux store import { updateAccessToken } from './redux/authSlice'; // Your Redux action for token updates // Instance for authorized requests (will have interceptors) const authAxios = axios.create({ baseURL: '/your-api-base-url', }); // Instance for public requests (no interceptors needed) const publicAxios = axios.create({ baseURL: '/your-api-base-url', });
Step 2: Add a Request Interceptor
This will automatically inject your auth token into the headers of any request marked as needing authorization. We’ll use a custom requiresAuth flag in the request config to distinguish them.
authAxios.interceptors.request.use( (config) => { if (config.requiresAuth) { const currentToken = store.getState().auth.accessToken; // Grab token from Redux if (currentToken) { config.headers.Authorization = `Bearer ${currentToken}`; } } return config; }, (error) => Promise.reject(error) );
Step 3: Add a Response Interceptor
This catches the new access token from server responses and updates your Redux state automatically.
authAxios.interceptors.response.use( (response) => { // Check if the response includes a fresh access token (adjust to match your API's structure) if (response.data?.newAccessToken) { store.dispatch(updateAccessToken(response.data.newAccessToken)); } return response; }, (error) => { // Optional: Handle token expiration or auth errors here (e.g., redirect to login) return Promise.reject(error); } );
How to Use It
Now making requests is straightforward—just use the right instance and flag authorized ones:
// Authorized request authAxios.get('/protected/user-data', { requiresAuth: true }) .then(res => /* handle response data */) .catch(err => /* handle errors */); // Public request (no auth required) publicAxios.get('/public/announcements') .then(res => /* handle response data */) .catch(err => /* handle errors */);
2. Custom API Wrapper Function (The Flexible, Explicit Solution)
If you prefer more granular control over individual requests (or don’t want to rely on interceptors), a custom wrapper function lets you encapsulate auth logic without global rules.
import axios from 'axios'; import { store } from './redux/store'; import { updateAccessToken } from './redux/authSlice'; const apiRequest = async (config) => { const { requiresAuth, ...restConfig } = config; let requestHeaders = restConfig.headers || {}; // Inject auth header if needed if (requiresAuth) { const currentToken = store.getState().auth.accessToken; if (currentToken) { requestHeaders.Authorization = `Bearer ${currentToken}`; } } try { const response = await axios({ ...restConfig, headers: requestHeaders }); // Update Redux with new token if present if (response.data?.newAccessToken) { store.dispatch(updateAccessToken(response.data.newAccessToken)); } return response; } catch (error) { throw error; } };
How to Use It
Call the wrapper for all your requests—no need to remember separate instances:
// Authorized request apiRequest({ method: 'POST', url: '/protected/update-profile', data: { name: 'New Name' }, requiresAuth: true }) .then(res => /* handle response */) .catch(err => /* handle errors */); // Public request apiRequest({ method: 'GET', url: '/public/landing-page-data' }) .then(res => /* handle response */) .catch(err => /* handle errors */);
Which Solution Should You Pick?
- Axios Interceptors: Ideal if most of your requests follow consistent auth rules. Once set up, you’ll never have to manually add headers or update tokens again—perfect for reducing repetitive code.
- Custom Wrapper: Better if you have edge cases (e.g., some requests need different token sources, or conditional token updates). It’s more explicit and gives you per-request control over auth logic.
Either way, both approaches will eliminate the duplication you’re dealing with. Pick the one that fits your project’s structure and needs best!
内容的提问来源于stack exchange,提问作者Thiem Nguyen

