In a nodeJs app, i am sending multipart/form-data to the server via ajax request. I am also using csurf package to guard against csrf attacks
Problem
When i submit my form without ajax request, everything works fine but when i submit my form using ajax request, i get invalid csrf token error on the server.
As far as i have understood the cause of this error, its because of cookies not sent with the request.
To send the cookies with ajax request, i set credentials: 'same-origin' in the post request made via fetch api but that didn't fix the issue. I also tried setting credentials: 'include' but that didn't make any difference.
Question
Is my understanding correct that this issue is because of cookies not being sent with ajax request and how can i fix this issue?
Code
let response = await fetch(requestUrl, {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'multiplart/form-data'
},
body: new URLSearchParams(form)
});
When using fetch()/AJAX with csurf, you need to pass the CSRF token as a request header:
// Read the CSRF token from a hidden input in the form
const token = document.querySelector('input[name="csrf-token"]').value;
// POST using the Fetch API
fetch('/<route.name>', {
headers: {
// pass the csrf token as a header
'CSRF-Token': token
},
method: 'POST',
body: {
...
}
});
Related
Can someone help me understand why it should have the config for this? What was headers or authorization does? Why should I put it as a second parameter?
dispatch({ type: 'FETCH_REQUEST' });
let config = {
headers: { authorization: `Bearer ${userInfo.token}` },
};
//Fetching the data from the backend
const { data } = await axios.get(`/api/orders/${orderId}`, config);
The header is essentially the header of the HTTP request. You need it for special config like authentication key, XSSR token, and other special config which you can read more in that link. The authorization is a authorization token. This is usually the JWT token that you got from the server when you've finished the authentication process. You can read more on the JWT authentication process here. Once you got the authorization token in your header of your request and send it to your server, your server will read in this token, deserialize it to get the data and determine if your HTTP request are valid and return the data. If your token is not valid, the server will throw an 403 (Unauthorize) error.
axios() has a whole number of ways you can specify the request you want.
For example, you can specify just a config object:
// Send a POST request
axios({
method: 'post',
url: '/user/12345',
data: {
firstName: 'Fred',
lastName: 'Flintstone'
}
});
Where the config object contains the method, url and other necessary options.
For all other types of requests, the config object is optional and is only needed if you need to specify some argument other than the URL or the data to send.
For example, with axios.get(), you can use either axios.get(someUrl) or axios.get(someUrl, config). The config object can contain all the options listed here in the doc. Among those options are custom headers, data to append to the URL (for a GET request), options for timeout, sending of credentials, basic auth, progress callbacks, etc....
All these options in the config object are optional. You only need to specify the ones that your particular request requires.
In the code example you show in your question:
let config = {
headers: { authorization: `Bearer ${userInfo.token}` },
};
//Fetching the data from the backend
const { data } = await axios.get(`/api/orders/${orderId}`, config);
This is specifying a custom header for the request that contains an authorization token that is presumably required by the server for this particular type of request so that in the headers of the http request, it will add something like this:
Authorization: Bearer someTokenValueHere
You can read about the authorization header here.
I have a DFR api endpoint:
url = http://127.0.0.1:8000/x/y/
Url of the page running JS code: http://127.0.0.1:8000/x/z/1/
I have logged in as User1 in my browser.
POST request - from DRF browser api - good.
GET request - from javascript - good.
POST request - from javascript - 403 error.
So perhaps I dont know how to make an authenticated ajax request from JS. When I do the same request from browser api, may be the browser takes care of authentication.
My current js code:
axios({
method: 'post',
baseURL: window.location.origin,
url: '/x/y/',
// adding auth header also gives same 403 error for post request
// headers: {
// Authorization: 'Token e77b8ca898b51cde72dcf2aa2c385942d771e972'
// },
data: {
name: 'xyz'
},
responseType: 'json',
})
.then(function (response) {
console.log(' success');
})
.catch(function (error) {
console.log(' error=', error.message);
});
If you are on chrome browser, go in console ctrl+shift+j and then go in network.
When a post request is made, we can see the error message in this network tab.
My post request had following error:
"CSRF Failed: CSRF token missing or incorrect."
To add csrf token on axios ajax request put following lines of code at beginning of your js file:
axios.defaults.xsrfCookieName = 'csrftoken';
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN";
Are you appending the CSRF token in your request,CSRF can cause 403 errors.Try appending csrf token in request headers
I'm trying to make an ajax call to service, my service api expects a Request Header for Authorization to give the response
Here is my JS code
var settings = {
url: "http://localhost:8080/codebluet-war/service/codeblue/facility",
method: "GET",
headers: {
"Authorization": "oauthtoken"",
}
}
$.ajax(settings).done(function (response) {
console.log(response)
});
I have added the Authorization headers in my code but still I'm getting 401 unauthorized request error.is there any other thing that I need to add in my settings?
If you are using OAuth 2.0 you should prefix the token value with Bearer word:
headers: {
"Authorization": "Bearer yourTokenValue",
}
With OAuth 1.0, it's a little bit more complicated since you need to send a set of parameters instead of a single token. Therefore, you may want to consider using a jQuery compatible OAuth library for this purpose.
I made the following post request to a 3rd party api, from my web frontend, using axios, but it couldn't go through.
Axios({
method: 'post',
url: 'https://some.website.com/oauth/token',
data: {
client_secret: 'revmisodtoire43-00j232onfkdl',
code: '54728349765905473289',
grant_type: 'authorization_code'
}
})
.then(res => {
console.log('client info: ', res);
});
The error says:Failed to load https://some.website.com/oauth/token: Response for preflight is invalid, and then network error.
When I made the same request via curl, it went through with no problem.
I know this is CORS related, but am not sure what to do with it. Any suggestions?
Check whether content-type is being added in the header's, if not try adding this
'Access-Control-Allow-Origin': '*' in the request headers
I'm trying to send a POST request from my website to my remote server but I encounter some CORS issues.
I searched in the internet but didn't find a solution to my specific problem.
This is my ajax request params:
var params = {
url: url,
method: 'POST',
data: JSON.stringify(data),
contentType: 'json',
headers: {
'Access-Control-Request-Origin': '*',
'Access-Control-Request-Methods': 'POST'
}
On the backend side in this is my code in python:
#app.route(SETTINGS_NAMESPACE + '/<string:product_name>', methods=['POST', 'OPTIONS'])
#graphs.time_method()
def get_settings(product_name):
settings_data = helper.param_validate_and_extract(request, None, required=True, type=dict, post_data=True)
settings_data = json.dumps(settings_data)
response = self._get_settings(product_name, settings_data)
return output_json(response, requests.codes.ok, headers = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST'
})
I get an error on my console:
XMLHttpRequest cannot load [http://path-to-my-server]. Request header field
Access-Control-Request-Methods is not allowed by
Access-Control-Allow-Headers in preflight response
I did notice that I can add also 'Access-Control-Request-Headers' but I wasn't sure if it necessary and it cause me more problems so I removed it.
Does anyone know how to solve this problem?
Your ajax request shouldn't send Access-Control headers, only the server sends those headers to allow the servers to describe the set of origins that are permitted to read that information using a web browser.
The same-origin policy generally doesn't apply outside browsers, so the server has to send CORS headers or JSONP data if the browser is going to be able to get the data.
The browser doesn't send those headers to the server, it doesn't have to, it's the server that decides whether or not the data is available to a specific origin.
Remove the header option from the params object, and it should work