I have two applications where spring is the backend and react is the frontend. I setup everything, including the response, so whenever I test using Postman, I always get the header below
and in the frontend, I setup like this:
Api.js
// api.js
import axios from 'axios';
import uri from "../routes/uri";
const instance = axios.create({
baseURL: uri.baseUrl, // Replace with your API base URL
headers: {
'Content-Type': 'application/json',
'Authorization':''
// 'Authorization': 'Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJsaW5kYSIsImF1dGhvcml0aWVzIjpbeyJhdXRob3JpdHkiOiJzdHVkZW50OndyaXRlIn0seyJhdXRob3JpdHkiOiJzdHVkZW50OnJlYWQifSx7ImF1dGhvcml0eSI6ImNvdXJzZTpyZWFkIn0seyJhdXRob3JpdHkiOiJST0xFX0FETUlOIn0seyJhdXRob3JpdHkiOiJjb3Vyc2U6d3JpdGUifV0sImlhdCI6MTY4OTM1MTg0NSwiZXhwIjoxNjkwMjE0NDAwfQ.Cw8-e6U_aQ-3SyDjmGKq5cDDcp-omv3fgEzoS2Aiwu69hrn8Wh3VmQgXstOQYUNfK4lt7npOIB-r26F8CCum6Q'
// You can add any other common headers here, such as authentication tokens, etc.
},
});
// instance.interceptors.request.use((config) => {
// // Add your custom headers here
// config.headers['Authorization'] = 'saasda';
// return config;
// });
instance.interceptors.response.use(
(response) => {
console.log('Response Data:', response.headers);
const customHeaderValue = response.headers['Authorization']; // Replace with your custom header key
if (customHeaderValue) {
instance.defaults.headers['Authorization'] = customHeaderValue; // Replace with your custom header key for requests
}
return response;
},
(error) => {
return Promise.reject(error);
}
);
export default instance;
ApiService.js
// apiService.js
import api from './api';
const apiService = {
async get(endpoint) {
try {
const response = await api.get(endpoint);
return response.data;
} catch (error) {
console.log(error);
throw new Error('An error occurred while fetching data.');
}
},
async post(endpoint, data) {
try {
const response = await api.post(endpoint, data);
return response.data;
} catch (error) {
console.log(error);
throw new Error('An error occurred while posting data.');
}
},
// Add other methods like PUT, DELETE, etc., as needed.
};
export default apiService;
And calling API
const handleGetRequest = async () => {
try {
const responseData = await apiService.post(uri.getEmployee);
const contentArray = Object.values(responseData.data.content); // convert into array since react can only disapl
setData(contentArray);
} catch (error) {
console.error(error);
// console.log(error.message());
}
};
I also tried setup the CORS config
const express = require('express');
const cors = require('cors');
const app = express();
// Allow specific origins (e.g., 'http://localhost:3000' for your React app)
const allowedOrigins = ['http://localhost:3000'];
// CORS middleware configuration
app.use(
cors({
origin: (origin, callback) => {
if (allowedOrigins.includes(origin) || !origin) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
},
})
);
// Your API routes and other configurations
// ...
const port = 8080;
app.listen(port, () => {
console.log(`Server started on port ${port}`);
});
However, in the browser, I only get a response . Why Authorization
does not appear in the browser response? and what should I do properly get the custom header from BE as response.
I tried to add header in response but the value must be coming from api/backend.
instance.interceptors.response.use(
(response) => {
response.headers['Authorization'] = '';
// console.log('Response Data:', response.headers);
const customHeaderValue = response.headers['Authorization']; // Replace with your custom header key
if (customHeaderValue) {
instance.defaults.headers['Authorization'] = customHeaderValue; // Replace with your custom header key for requests
}
return response;
},
(error) => {
return Promise.reject(error);
}
);
2
Answers
After days of trial, I found the error. Apparently, the issue seems to be using
apiService
as the wrapper. Whenever the request is made, the application does not have the same response header as the request. There's no need to set up extra proxy config and credentials.So here is my new wrapper.
apiWrapper.js
api.js
and to use it,
You can use withCredentials property.
Also its possible to force credentials to every Axios requests
Or using credentials for some of the Axios requests as the following code
By setting { withCredentials: true } you may encounter cross origin issue. To solve that you need to use
You can also play around the headers response and Access-Control-Allow-Headers to indicate which HTTP headers can be used during the actual request.
Note that the Authorization header always needs to be listed explicitly