I'm trying to make a dojo xhrGet request using basic authentication but I keep getting 403 forbidden error. I can make the request with curl from the command line, so I know my credentials are valid. When I check the request headers, the Authorization: Basic header isn't even being set. What am I doing wrong:
var lookupArgs = {
url: "https://myendpoint.com/myapi/endpoint",
user:"myemail#myendpoint.com",
password:"mypassword",
handleAs: "text",
load: function(data) {
content_node.innerHTML = data;
},
error: function(error) {
content_node.innerHTML = error;
}
}
dojo.xhrGet(lookupArgs);
Request Header:
GET /myapi/endpoint HTTP/1.1
Host: myendpoint.com
Connection: keep-alive
Origin: http://my-origin
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3315.3 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept: */*
Referer: http://my-origin
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Related
I'm tryng to perfom a simple ajax post request to retrieve some data from a website.
In detail i'm trying to contact a page that a website recall to have some informations.
So i have the main website and a page that it calls to retrive data.
I discovered that page using the google inspection section, in particular in the xhr section of network field of the inspector.
In my code i used all the headers and the payload data that are used by the website to contact the page.
This is the code that i'm using to reach my goal:
var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
var url = 'https://www.remax.pt/Webservices/MainWebService.asmx/GetCityList';
var body = {"SiteRegionID":"12","RegionID":"12","RegionRowID":"78","ProvinceID":"0",
"LanguageCode":"ITA","MinInternetCount":"0","SearchType":"","OfficeAgent":"0",
"EncodingLanguage":"PTG","OfficeAgentId":"0"};
var xhr = new XMLHttpRequest();
xhr.onload = function () {
var data = xhr.responseText;
if (xhr.readyState == 4 && xhr.status == "200") {
console.table("results: "+data);
} else {
console.error("error: "+data);
}
}
xhr.open("POST", url, true);
xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
//xhr.setRequestHeader("Content-Type","text/html");
xhr.setRequestHeader("Access-Control-Allow-Origin","*");
xhr.setRequestHeader("accept", "application/json, text/javascript, */*; q=0.01");
xhr.setRequestHeader("authority", "www.remax.pt");
xhr.setRequestHeader("scheme", "https");
xhr.setRequestHeader("path", "/Webservices/MainWebService.asmx/GetCityList");
xhr.setRequestHeader("accept-language","it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7");
//xhr.setRequestHeader('accept-encoding', 'gzip, deflate, br');
//xhr.setRequestHeader("host", "https://www.remax.pt");
//xhr.setRequestHeader('referer', 'https://www.remax.pt/PublicListingList.aspx');
//xhr.setRequestHeader('content-length', '192');
//xhr.setRequestHeader('cookie','__cfduid=dc7dd48ccff40ee4f85840bfc35685b311531384150; PersonalizationMap=; PersonalizationGallery=SelectedCountryID=12; GtTransLang=ITA; SLINGSHOT=LanguageCode=it-IT; SessionId=1ac0ec84-6a03-4965-ba90-7eb686f66bf5; ASP.NET_SessionId=rgia1pblms2abf11ypsbiqgz; GtTrans=ENU; LastSearch=SiteRegionID=12&TransactionTypeUID=260&RegionID=12&RegionRowID=78&LocationText=Porto&LocationValue=YR78&PriceCurrency=EUR&ComRes=2; PersonalizationRegion=#mode=list&tt=260&cr=2&r=78&cur=EUR&la=All&sb=PriceIncreasing&page=1&sc=12&sid=a81a1d1d-ee36-4236-a72e-31343349c574; PersonalizationDate=2018-7-24 10:0:30');
xhr.setRequestHeader("user-agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36");
xhr.setRequestHeader("x-requested-with", "XMLHttpRequest");
xhr.send(JSON.stringify(body);
Actually i never receive an answer. I think that the flow of operations never enter in the onLoad section because the string that there are in if and else sections are never printed.
I wanna specify that some headers are commented because i had an answer of this type:
Refused to set unsafe header 'nameHeader'
So i decided to do not use them for the moment.
I tried to change some headers or add something new but the problem remains and honestly i don't have idea if it is a problem of syntax of some fields or if i need other things to perform an acceptable request.
for completeness i insert the 4 fields that i found in the inspector tool that specify the parameters passed by the website to call the page:
GENERAL:
1. Request URL:
https://www.remax.pt/Webservices/MainWebService.asmx/GetCityList
2. Request Method: POST
3. Status Code: 200
4. Remote Address: 104.25.40.105:443
5. Referrer Policy: no-referrer-when-downgrade
RESPONSE HEADERS:
List item
cache-control: private, max-age=0
cf-ray: 43f532b9e9886260-LIS
content-encoding: br
content-type: application/json; charset=utf-8
date: Tue, 24 Jul 2018 09:00:44 GMT
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
server: cloudflare
status: 200
x-aspnet-version: 4.0.30319
x-ua-compatible: IE=9, IE=8
REQUEST HEADERS:
authority: www.remax.pt
method: POST
path: /Webservices/MainWebService.asmx/GetCityList
scheme: https
accept: application/json, text/javascript, /; q=0.01
accept-encoding: gzip, deflate, br
accept-language: it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7
content-length: 192
content-type: application/json; charset=UTF-8
cookie: __cfduid=dc7dd48ccff40ee4f85840bfc35685b311531384150; PersonalizationMap=; PersonalizationGallery=SelectedCountryID=12; GtTransLang=ITA; SLINGSHOT=LanguageCode=it-IT; SessionId=1ac0ec84-6a03-4965-ba90-7eb686f66bf5; ASP.NET_SessionId=rgia1pblms2abf11ypsbiqgz; GtTrans=ENU; LastSearch=SiteRegionID=12&TransactionTypeUID=260&RegionID=12&RegionRowID=78&LocationText=Porto&LocationValue=YR78&PriceCurrency=EUR&ComRes=2; PersonalizationRegion=#mode=list&tt=260&cr=2&r=78&cur=EUR&la=All&sb=PriceIncreasing&page=1&sc=12&sid=a81a1d1d-ee36-4236-a72e-31343349c574; PersonalizationDate=2018-7-24 10:0:30
origin: https://www.remax.pt
referer: https://www.remax.pt/PublicListingList.aspx
user-agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36
x-requested-with: XMLHttpRequest
REQUEST PAYLOAD:
{"SiteRegionID":"12","RegionID":"12","RegionRowID":"78","ProvinceID":"0","LanguageCode":"ITA","MinInternetCount":"0","SearchType":"","OfficeAgent":0,"EncodingLanguage":"PTG","OfficeAgentId":0}
I'm sending POST data with AJAX:
const form = d.getElementById('form');
form.addEventListener('submit', SendData);
function SendData(e) {
e.preventDefault();
var data = e.target.getElementsByTagName('input')[0].value.trim();
var xhr = new XMLHttpRequest();
xhr.addEventListener('load', function(event){
console.log(event.target.responseText);
});
xhr.addEventListener('error', function(event){
console.log(event.target.statusText);
});
xhr.open('POST', '/db', true);
xhr.send('data=' + data);
}
But when I use IE11, server receives data only once in every two requests:
1:
POST http://localhost:99/db HTTP/1.1
Accept: */*
Referer: http://localhost:99/
Accept-Language: ru
Content-Type: text/plain;charset=UTF-8
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like
Gecko
Host: localhost:99
Content-Length: 13
Connection: Keep-Alive
Cache-Control: no-cache
data=01234567
2:
POST http://localhost:99/db HTTP/1.1
Accept: */*
Referer: http://localhost:99/
Accept-Language: ru
Content-Type: text/plain;charset=UTF-8
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like
Gecko
Host: localhost:99
Content-Length: 13
Connection: Keep-Alive
Cache-Control: no-cache
I noticed, when I use Fiddler for debugging, server receives data every time. Couldn't anybody explain to me this behavior, and how to fix it?
Did you try to use jQuery ajax functionality? This has the advantage that it is working across browsers flawlessly, and needs only one syntax. I know, that most people do not like to use additional frameworks, but this one simplifies coding a lot.
e.g.:
$.ajax({
url:'https://my.server.com/myscript.php,
type:'post',
data: {
var1: "x",
var2: "y",
},
success: function(data) {
// here goes the data, returned from your php script e.g.
}
});
I'm tring to add a header called "access-token" to all my http request like this:
var app= angular.module("MainModule", ["ngRoute"]);
app.run(function($http){
$http.defaults.headers.common['access-token'] =ACCESSTOKEN;
})
and in my service:
service.get= function (x) {
console.log(ACCESSTOKEN)
return $http({
method: "GET",
headers: {
'Content-Type': 'application/json',
'access-token': ACCESSTOKEN
},
crossDomain: true,
url: GETSERVICE.replace("{id}", x),
dataType: 'json'
}).then(function (response) {
if (response.data) {
return response.data;
} else {
return $q.reject(response.data);
}
}, function (response) {
return $q.reject(response.data);
});
}
the problem is that i can't see the header in the network. There is only the OPTION request without my header.
my Back end cors configuration is like:
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, UPDATE, OPTIONS");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, access-token");
chain.doFilter(req, res);
Any ideas how to fix it?
TY
EDIT 1:
Here is the OPTION request without modifiy headers
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7
Access-Control-Request-Headers: access-token
Access-Control-Request-Method: GET
Cache-Control: no-cache
Connection: keep-alive
Host: localhost:8081
Origin: http://localhost:9080
Pragma: no-cache
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36
and whit modify headers (worked):
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7
Access-Control-Request-Headers: access-token
Access-Control-Request-Method: GET
access-token: 1520963789861
Cache-Control: no-cache
Connection: keep-alive
Host: localhost:8081
Origin: http://localhost:9080
Pragma: no-cache
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36
whit modify headers I have the token in the request
CORS exists to secure APIs so that random clients do not make calls to them.
JavaScript has to take permissions to be able to make calls to those APIs. Browser is supposed to do all the heavy lifting related to CORS. But the only requirement is that the server should return the following HTTP headers for an OPTIONS request from a client:
Access-Control-Allow-Origin: <Origin fetched from the request>
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, DELETE
Access-Control-Allow-Headers: <ACCESS-CONTROL-REQUEST-HEADERS fetched from request>
If that is NOT an option, then on the client side, following code can be added to prevent all OPTIONS requests, which compromises security:
app.config(['$httpProvider', function ($httpProvider) {
$httpProvider.defaults.headers.common = {};
$httpProvider.defaults.headers.post = {};
$httpProvider.defaults.headers.put = {};
$httpProvider.defaults.headers.patch = {};
$httpProvider.defaults.headers.get = {};
}]);
See: https://en.wikipedia.org/wiki/Cross-origin_resource_sharing
That OPTIONS request is called "preflight request". It only checks if your client has a right to send a request at all (when a server has a configured CORS). If server responds positively then your browser automatically send a full request with all you provided headers.
$httpProvider or $http module:
//with the provider, in the app.config():
$httpProvider.defaults.headers.post['Content-Type'] = 'application/json; charset=utf-8';
$http.defaults.headers.common['Content-Type'] = 'application/json; charset=utf-8';
Ok I will tell you what were the problem.
The genial man who write the rest api that I call in cross domain checked the value of the token also in the OPTION request going in null pointer.
Solved adding a filter for the option request.
TY for all
I am performing a fetch:
fetch(url, fetchOptions);
fetchOptions is configured like so:
var fetchOptions = {
method: options.method,
headers: getHeaders(),
mode: 'no-cors',
cache: 'no-cache',
};
function getHeaders() {
var headers = new Headers(); // Headers is part of the fetch API.
headers.append('User-ID', 'foo');
return headers;
}
Checking fetchOptions at runtime it looks as follows:
fetchOptions.headers.keys().next() // Object {done: false, value: "user-id"}
fetchOptions.headers.values().next() // Object {done: false, value: "foo"}
But user-id is nowhere to be found in the request headers per Chrome dev tools:
GET /whatever?a=long_name&searchTerm=g HTTP/1.1
Host: host:8787
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
accept: application/json
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36
Referer: http://localhost:23900/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,fr;q=0.6
Why can I not see my "User-ID" header in Chrome dev tools, and why does the header key appear to have been lowercased?
Incase someone else has a similar problem there were two possible culprits for this:
I might not have been starting Chrome with the correct flags.
The following didn't work when run from a Windows shortcut:
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" -enable-precise-memory-info -disable-web-security
The following did work when run from a Windows command prompt:
C:\whatever\48.0.2564.82\application\chrome.exe --disable-web-security --user-data-dir=C:\whatever\tmp\chrome
The addition of no-cors to the mode of the request might have caused an OPTIONS request to precede the GET request and the server did not support OPTIONS.
I've been stuck at this for a while now. I have ajax request here:
$.ajax({
url: UPDATE_USER_INFO_URL ,
type: "POST",
dataType: "json",
contentType: "application/json",
data: JSON.stringify({user:'user'}),
success: function (data, textStatus) {
if(data["statusCode"] && data["statusCode"] == 1) {
_callback(1,data);
}
else {
_callback(0,data);
}
},
error: function (jqXHR, textStatus){
_callback(0, {});
}
});
If I set UPDATE_USER_INFO_URL to a specific URL, fiddler show nothing in the body. If I set UPDATE_USER_INFO_URL to something else (even invalid URL), it does put {user:'user'} in the body in fiddler.
With original UPDATE_USER_INFO_URL:
POST http://10.35.50.26:8080/SelfServiceWs/user/session/upduserinfo HTTP/1.1
Accept: application/json, text/javascript, ; q=0.01
Content-Type: application/json
X-Requested-With: XMLHttpRequest
Referer: http://10.35.50.26:8080/SelfService/
Accept-Language: en-us
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Host: 10.35.50.26:8080
Connection: Keep-Alive
Pragma: no-cache
Cookie: JSESSIONID=0BF9D9CCCE9030E60AB0BCE5F6562CD8
Authorization: Negotiate TlRMTVNTUAABAAAAl4II4gAAAAAAAAAAAAAAAAAAAAAGAbAdAAAADw==
Content-Length: 0
Chage url to /SelfServiceWs/abcdef
POST http://10.35.50.26:8080/SelfServiceWs/abcdef HTTP/1.1
Accept: application/json, text/javascript; q=0.01
Content-Type: application/json
X-Requested-With: XMLHttpRequest
Referer: http://10.35.50.26:8080/SelfService/
Accept-Language: en-us
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Host: 10.35.50.26:8080
Content-Length: 15
Connection: Keep-Alive
Pragma: no-cache
Cookie: JSESSIONID=9E79779805579A7964E03AAD76DF043B
{"user":"user"}
I have many other ajax calls, all are working as expected.
It must be little thing that I am missing.
I figured this out.
I have an authentication servlet filter to url /user/ssoauth, unexpectedly (to me), it made eveything call to URL under /user path (including /user/session/upduserinfo) to send out Authorization header. Moved filter to /user/auth/ssoauth stop client to send authorization header when calling user/session/upduserinfo and fix the problem.
<filter-mapping>
<filter-name>SecurityFilter</filter-name>
<url-pattern>/user/ssoauth</url-pattern>
</filter-mapping>
cause every client call to URL after /user to send Authorization header.
I learned something new today!
try this
data: JSON.stringify({'user':'user'}),