I am trying to set a custom header on every response my Express api sends, so I wrote a simple middleware:
app.use((request, response, next) => {
response.setHeader("custom-header", "value");
next();
});
But when I inspect the headers received on my ReactJS application using axios interceptor, it simply doesn't appear. Here is my interceptor:
import axios from "axios";
const api = axios.create({
baseURL: "http://localhost:3333"
});
api.interceptors.response.use(
response => {
console.log(response.headers);
return response;
},
error => {
console.log(error)
return Promise.reject(error);
}
);
export default api;
Just in case it may be relevant, my express app also uses cors, helmet and express.json middlewares, but I already tryied removing them and still I wasn't able to receive the header on the client.
What would be the appropriate way to set and receive a custom header on every request?
So ironically a few minutes after posting the question I finally found the solution (which I was looking for for hours):
Turns out it is necessary to configure Access-Control-Expose-Headers on the cors middleware configuration, like this:
app.use(
cors({
exposedHeaders: ["custom-header"]
})
);
Related
I want to hide some information such as bearer token and API key in header. I have been heard about ssr and using proxy to hide that information, but how? Can someone tell me how to do that? Or is that possible to do in client side?
I tried with some ssr that fetch in react, but it doesn't work for me. I also tried with proxy, but that works for API key that didn't need a dynamically params like user token.
To use server-side rendering (SSR), you will need to install and import the following packages: express, cors, and Axios. The cors middleware allows for Cross-Origin Resource Sharing, while Axios is used to make HTTP requests to external APIs or databases, and handle the response data asynchronously. By setting the headers with Axios, you can pass along sensitive information such as API keys and bearer tokens. After receiving the data back, you can destructure it from the Axios response and then send it back to your users by using the res.json() method.
const cors = require('cors');
const axios = require('axios');
const app = express();
app.use(cors());
app.get('/api/data', async (req, res) => {
try {
const { data } = await axios.get('https://api.example.com/data', {
headers: {
Authorization: `Bearer ${process.env.BEARER_TOKEN}`,
'API-Key': process.env.API_KEY,
},
});
res.json(data);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.listen(3000, () => {
console.log('Server started on port 3000');
});
My React host has an IP of 10.60.160.61.
The API endpoint that I'm trying to reach has an IP of 10.200.50.21.
My App.js:
useEffect(() => {
const fecthPods = async () => {
try {
const response = await axios.get(`https://kubernetes.endpoint.com/k8s/clusters/name/v1/pods/myproject`,{ headers: { 'Authorization': 'Bearer token-myToken' } })
console.log(response.data)
} catch (err) {
if (err.response) {
// Not in the 200 response range
console.log(err.response.data)
console.log(err.response.status)
console.log(err.response.headers)
} else {
console.log(`Error: ${err.message}`)
}
}
}
fecthPods()
},[])
I get two errors in the network tab of developer tools:
401
CORS preflight
I can access an external API endpoint with no issue (ie. https://pokeapi.co/api/v2/pokemon/ditto).
I can successfully run a curl command to the Kubernetes API endpoint by passing the Auth token in the headers parameter, but just not working with Axios.
I don't think I need to run a backend express server since the API endpoint that I'm trying to reach is not on my localhost.
Not sure what else to try.
I believe I have found the answer to this question. Seems like I will need to run my API calls through a custom proxy as mentioned in this post.
I build a ionic-react android application with Axios to get a server response. Two weeks ago my code was working fine. Now the axios request always returns a NETWORK_ERR (HttpError or Axios Error).
I tried to use all CORS Headers possible in my api, but the request is not sent to the webservice.
I hope anyone can help me:
This is the Code I was using:
const api = axios.create({
baseURL: "http://192.168.0.145:8080/RestFulTest-1.0-SNAPSHOT/api",
});
function callApi(){
api.get("/verification")
.then((res) => {
console.log(res);
})
.catch((error) => {
console.log(error);
});
}
Just directly opening the API Url in browser is not loading it...
Sot it seems either the backend is down or blocking and requires an authorization header with the axios request, like
let tokenStr = "Your TOKEN";
axios.get("/verification", { headers: {"Authorization" : `Bearer ${tokenStr}`} });
Hope it helps..
I am trying to do a post request with axios to upload a image to cloudinary from my frontend React app. I am getting this error from the axios code below:
http://localhost:3000 has been blocked by CORS policy: Request header field x-access-token is not allowed by Access-Control-Allow-Headers in preflight response.
Using axios, doesnt work gives me cors error
await axios({
method: "POST",
url: "https://api.cloudinary.com/v1_1/******/image/upload/",
data: {
file: img,
upload_preset: "*****",
cloud_name: "****",
},
})
.then((res) => {
console.log("response");
console.log(res);
})
.catch((err) => console.log(err));
Meanwhile when i use fetch using the same api request, the post request works and doesnt give me error. Anyone know why and how to call the api using axios?
const data = new FormData();
data.append("file", img);
data.append("upload_preset", "*****");
data.append("cloud_name", "*****");
await fetch(
" https://api.cloudinary.com/v1_1/****/image/upload/",
{
method: "post",
body: data,
}
)
.then((resp) => resp.json())
.then((data) => {
setUrlArray((prevState) => [...prevState, data.url]);
})
.catch((err) => console.log(err));
Extra info: My upload preset is unsigned.
Also got this from the console after making the axios api call
{
error: {
message: "Upload preset must be specified when using unsigned upload"
}
}
To create an Axios request equivalent to your working fetch() one, you need to
Craft a FormData instance and set it as the request data so your content-type is multipart/form-data
Make sure you're not using a previously created Axios instance with unwanted default headers
If custom headers have been set on the default Axios instance, eg
axios.defaults.headers.common["x-access-token"] = TOKEN
you may need to override / delete them in transformRequest
To avoid any interceptors defined on the default Axios instance, create a new separate instance for un-intercepted requests
import axios from "axios" // import the default instance
// create a new instance without interceptors.
// you could also create this in its own module and import from there
const instance = axios.create()
const data = new FormData()
data.append("file", img);
data.append("upload_preset", "*****");
data.append("cloud_name", "*****");
const res = await instance.post(
"https://api.cloudinary.com/v1_1/******/image/upload/",
data
)
Ideally, if your app is going to customise requests, you should always use an Axios instance (or multiple instances) to avoid messing around with the defaults.
I have a backend with laravel sanctum implementation, all config are working correctly.
On the frontend I use react, an action is dispatched to login, for example.
X-XSRF-TOKEN must be set before hitting the endpoint, thus I must call /sanctum/csrf-cookie first, I've ran into these problems:
If I try and get the csrf token in createAsyncThunk first, and then /login, redux toolkit assumes the request is fulfilled, thus changing the state before the login api is called
I have no idea why when I create an axios instance, the X-XSRF-TOKEN is not being set in the header, but when I use axios imported normally, it works.
Action
export const login = createAsyncThunk("auth/login", async (_) => {
try {
request.get("sanctum/csrf-cookie").then((response) => {
// THE PROBLEM OCCURS HERE, no header is received, (request is instantiated below, if I import axios it works)
const res = await request.post("/login", _);
return res.data;
// this one failed with 419 csrf token mismatch, eventually because X-XSRF-TOKEN is not set, im not sure why
});
} catch (err) {
throw err;
}
});
axios
import axios from "axios";
export const request = axios.create({
baseURL: `http://localhost:8000/`,
headers: {
Accept: "application/json",
},
});
axios.defaults.withCredentials = true;
Note: The backend is working and configued correctly, because if I do not create an instance and just import and use axios, the request is working, but I'm back with problem 1, where the thunk is fulfilled on the first request (before return response.data), and i'm not interested in such a solution, I don't need to copy the code
Summary:
The sanctum/csrf-cookie response has no X-XSRF-TOKEN header, only when creating an axios instance using axios.create, a cookie is received though
Perhaps the header is resetting to its default on the second request? how can I append the headers from the first request? Thanks
-- Should I try instead of calling sanctum/csrf-cookie in all requests like this, intercept the request and somehow append the header to the request?
Any help, examples, guides are appreciated
rookie mistake, was using axios.defaults.withCredentials = true;
instead of axiosInstance.defaults.withCredentials = true;