Axios - Different headers for Express Request - javascript

I start to develop an SSR React-Redux application, and i have a problem with axios headers.
What is the proper way to set different header for each Express request?
Express.get('*', async (req, res) => {
axios.defaults.headers.common = req.headers['my-customer-id'];
// first axios get request
// second axios get request
// thirth axios get request
//... initialization React App
});
With this approach, axios default headers are overwritten from last Express request.
I try to create different axios instance with axios.create(), but i don't know where and how to save the instance, for use inside application modules.

there is a different between global headers and instance only headers:
// affects the global instance
axios.defaults.headers.common['Auth-Token'] = 'foo bar';
// affects to a single instance
axiosInstance.defaults.headers['Auth-Token'] = 'foo bar';
this works for me inside an expressjs app too, with different services (instances of axios)

You can create a new custom instance of axios using create.
const customAxios = axios.create({
headers: {...req.headers['my-customer-id']}
});
Now use customAxios to make the request
customAxios.get(...)

Related

How do I set the origin in the DeepL API on javascript?

What else should I try?
I'm currently sending a request to the DeepL API in axios, but I'm getting a 403 response due to a CORS issue.
And tried to set the option using querystring as shown here, but it didn't work. https://github.com/funkyremi/deepl/blob/master/index.ts
Also, using the library at the URL above returns 403.
Furthermore, there is no origin setting in the account settings of DeepL.
I tried using 'Content-Type': 'application/x-www-form-urlencoded' for axios headers: {}, and I also tried setting options for params: { } and not using querystring, but they didn't work.
import axios from 'axios'
import querystring from 'querystring';
export const translateDeepL = async() => {
const options = {
"auth_key": process.env.DEEPL_AUTH_KEY,
"text": 'everyday is birthday.',
"target_lang": 'JA',
};
const url = "https://api-free.deepl.com/v2/translate";
const data = await axios.post(url, querystring.stringify(options)).then(r => r);
console.log(data);
}
VM3451:1 POST https://api-free.deepl.com/v2/translate 403
the request use https with ngrok did't work also.
I also tried the GET method for "https://api-free.deepl.com/v2/usage" but got the same result.
It is definitely api-free.deepl.com since I am using the free plan.
By the way, the above code is executed as a component in React.
the DeepL API does not support being used directly from within browser-based apps. The API Key is not supposed to be shared publicly as well and should always be kept secret.
The best approach is to use a backend proxy for the API Calls.
I was encountering this same issue and couldn't find an answer. This API just didn't seem to want to talk to me via a browser.
My 'solution' was to set up an API proxy in node.
It works fine fetching from a back-end + now I can add some rate limiting etc
C.J on coding garden can explain this way better than I ever can.
You might be being blocked because of sending a request from http (your localhost) to https, try using the proxy axios config, like
const response = await axios
.get("https://api-free.deepl.com/v2/translate", {
params: {
auth_key: x,
text: y,
target_lang: z
},
proxy: {
host: "localhost",
port: 8080
}
});
return response;
};

Route that is executed within another route in Node.js is not being executed

Good Evening,
I have a function that contains a route that is a call to the Auth0 API and contains the updated data that was sent from the client. The function runs, but the app.patch() does not seem to run and I am not sure what I am missing.
function updateUser(val) {
app.patch(`https://${process.env.AUTH0_BASE_URL}/api/v2/users/${val.id}`,(res) => {
console.log(val);
res.header('Authorization: Bearer <insert token>)
res.json(val);
})
app.post('/updateuser', (req, ) => {
const val = req.body;
updateUser(val);
})
app.patch() does NOT send an outgoing request to another server. Instead, it registers a listener for incoming PATCH requests. It does not appear from your comments that that is what you want to do.
To send a PATCH request to another server, you need to use a library that is designed for sending http requests. There's a low level library built into the nodejs http module which you could use an http.request() to construct a PATCH request with, but it's generally a lot easier to use a higher level library such as any of them listed here.
My favorite in that list is the got() library, but many in that list are popular and used widely.
Using the got() library, you would send a PATCH request like this:
const got = require('got');
const options = {
headers: {Authorization: `Bearer ${someToken}`},
body: someData
};
const url = `https://${process.env.AUTH0_BASE_URL}/api/v2/users/${val.id}`;
got.patch(url, options).then(result => {
console.log(result);
}).catch(err => {
console.log(err);
});
Note: The PATCH request needs body data (the same that a POST needs body data)

Axios POST params show empty on server - using MERN stack

I want to update a document in Mongo, but when I send an Axios POST request to the server with params for the updates I receive nothing but a blank object on the server side - I'm using Node.js with an Express server (MERN stack).
I have tried the qs library module and Node's querystring module. I tried including headers with
'Content-Type': 'application/x-www-form-urlencoded' and 'application/json'.
My Axios POST request:
const A = 1;
const B = 2;
const data = { A, B };
console.log(qs.stringify(data)); // A=1&B=2
axios.post(url('upVote'), qs.stringify(data));
The server route:
app.post('/upVote', async (req, res) => {
console.log(req.params); // {}
await DB.updateVote(ID, collection, voteCount);
res.end();
});
The headers as shown by Chrome's DevTools.
... Also, all my axios.get() requests work fine and grab data from Mongo and send it back to my app properly, and the url/endpoints match.
There are a couple of ways to send data to the server with axios.
I see the confusion with the documentation in axios, I have not seen this usage before and it does seem to be broken upon looking at the request logs and object.
1) axios.post receives body of the request as a second parameter. So if you want to pass parameters to axios, you should do something like this:
const B = 2;
const data = { A: 1, B: 1 };
axios.post(url('upVote'), {}, { params: data });
Note that axios will handle stringification on it's own and that the third parameter is a config object.
On the server the params will be available at request.query
2) If you want to stringify the parameters yourself, then you should append them into your URL like so
axios.post(`url('upVote')?${qs.stringify(data)}`);
Same here, data on the server will be under request.query
3) It's generally better to use the body of the post request to transfer large data payloads for convenience. You should also consider what your caching strategies are and if they rely on request url without the consideration of request body it may be a concern.
axios.post(url('upVote'), data);
In this case data on the server will be under request.body
UPD: Originally forgot to mention that you will need a body-parser middleware to access request.body.
4) You can use axios without method shorthands which may be useful for some people
axios({
method: 'POST',
url: url('upVote'),
params: data
})
This is identical to the example in 1.
And all of them return a Promise which you can .then().catch() or await.
I think you want .body instead of .params.As you are sending data in body by post using axios. You are printing params which will print nothing for this url/api .
Try
console.log(req.body) // instead of req.params
If this did not work then please show us your react code.
Moreover
In react you have to add .then() after axios else it will say unhanded promise
To get params on server side you have to make some changes
In axios (react)
axios.post(url('upVote/param'), qs.stringify(data));
In server
app.post('/upVote/:params', async (req, res) => {
console.log(req.params)
.....
})
I think you are calling res.end(). I think it should be res.send(...)
This answer should help: https://stackoverflow.com/a/29555444/1971378

Updating the axios instance header failed after login to the application

I am developing an application using React js in Redux architecture
and used axios for http requests.
I have two container classes one is login and another one is home
page. In routes class i import both the container classes.
In home page container i import one action and that action imports
one axios instance variable
export var Instance_Variable = axios.create({
baseURL: URL,
headers: {
"AUTH-TOKEN": localStorage.getItem("AuthToken")
}
});
In my scenario,
the routs file will import these instance variable while importing home page class.
While login i get the auth token from the response and set it to the local storage. After logging in there was one request made in home page and respond with unauthorized(401 - The auth token validation done in application).
I am view the network tab in browser and the request made with the header "AUTH-TOKEN" : null
How do i update the instance after logging in to the application
Note: The request are works well after refreshing the application after loggin
Hello I know it’s a very old question but today I also faced this same issue and Hopefully able to solve this problem also
So, when you call the 'login API URL with Axios, if this request succeeded then you have set the header in Axios '.then' block like they said here
instance.defaults.headers.common['Authorization'] = AUTH_TOKEN;
Note: for this, you must have to use Axios interceptor
It is better to use an axios interceptor that sets header for every request like below:
axios
.interceptors
.request
.use(function (config) {
if (cookie.load('auth-token')) {
config.headers['AUTH-TOKEN'] = cookie.load('auth-token');
}
return config;
}, function (error) {
return Promise.reject(error);
});

Hiding api url in react/redux application (proxy)

I am concerned about security of my react/redux application as my api url is exposed to the public inside bundled app.js file. I've been researching this and some developers proxy it somehow i.e. instead of using my api url I can use api/ whenever I perform calls with libraries like axios or superagent and it gets proxied to my api url, but this way users can only see api/ on their side.
I'm trying to figure this out, I assume this is set up within express config?
You have a valid concern.
Typically you would have your clientside code make calls to, say, /api, and in express (or whatever server you use) create a route for "/api" that proxies that request to the actual api url.
This way you can obscure any sensitive information from the client. For example authentication tokens, api keys, etc.
In express you could do something like this:
app.use('/api', (req, res) => {
const method = req.method.toLowerCase();
const headers = req.headers;
const url = 'your_actual_api_url';
// Proxy request
const proxyRequest = req.pipe(
request({
url
headers,
method,
})
);
const data = [];
proxyRequest.on('data', (chunk) => {
data.push(chunk);
});
proxyRequest.on('end', () => {
const { response } = proxyRequest;
const buf = Buffer.concat(data).toString();
res.status(response.statusCode).send(buf);
});
});
This example is a bit more elaborate that is has to be, but it will probably work for you.

Categories