I am using JS to access the rdio plugin. I am using the following for Oauth http://code.google.com/chrome/extensions/tut_oauth.html.
I am able to get the signed token etc. However, when ever I try to send a signedRequest at http://api.rdio.com/1/, I receive 401, un-authorized error.
X-Mashery-Error-Code:ERR_401_INVALID_SIGNATURE
X-Mashery-Responder:mashery-web4.LAX
This is what I am trying to send:
var url = 'http://api.rdio.com/1/';
var request = {
'method': 'POST',
'headers': {
'Content-Type': 'application/x-www-form-urlencoded'
},
'parameters': {
'alt': 'json',
'method':'currentUser'
},
'body': 'Data to send'
};
bgPage.oauth.sendSignedRequest(url, mycallback, request);
I receive the following error in console.
Request URL:http://api.rdio.com/1/?alt=json&method=currentUser&oauth_consumer_key=yv8ehzehdv55**********&oauth_nonce=******&oauth_signature=**********&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1305190893&oauth_token=us6myp99p4qc86umea9p8fp*****************
Request Method:POST
Status Code:401 Unauthorized
Request Headers
Accept:*/*
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:12
Content-Type:application/x-www-form-urlencoded
Cookie:__qca=P0-158278476-1296771701175; r=eyJfdSI6IDE5MjY1LCAiX2UiOiAzMTU1NjkyNn0.SvN8xd7rIuLzTp7hxqi4eJEdvu8; __utmz=225830489.1305153361.198.18.utmcsr=rdioquiz.ianloic.com|utmccn=(referral)|utmcmd=referral|utmcct=/; __utma=225830489.281668250.1296676147.1305184513.1305187119.201; __utmc=225830489
Host:api.rdio.com
Origin:chrome-extension://oiojbkkpmcgmpnjkhjmaggajckamjkap
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_6) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.65 Safari/534.24
Query String Parameters
alt:json
method:currentUser
oauth_consumer_key:yv8ehzehdv55pbb74ss9dt23
oauth_nonce:BQF0x
oauth_signature:KttF************tRO 8PL yjPF2Ktk=
oauth_signature_method:HMAC-SHA1
oauth_timestamp:1305190893
oauth_token:us6myp99p4qc86umea9p8fphbgq4dxdd76txvyn***********
Form Data
Data to send:
Response Headers
Accept-Ranges:bytes
Content-Length:30
Content-Type:text/xml
Date:Thu, 12 May 2011 09:01:33 GMT
Server:Mashery Proxy
X-Mashery-Error-Code:ERR_401_INVALID_SIGNATURE
X-Mashery-Responder:mashery-web4.LAX
*I am just trying to mimic what's mentioned here. Its an Oauth library(http://code.google.com/chrome/extensions/tut_oauth.html) from Google to make Chrome extension development easy.
They have an Oauth sample code to get your document list etc. http://code.google.com/chrome/extensions/samples.html#4e35caa9742fb82dbd628892d23a781614f6eff6
I think I am not able to get past send a POST requestto the rdio API. It gives an un-authorized error.*
We found a similar issue with the same service (rdio) and method ("currentUser").
What ended up working was:
(1) make sure you have method=currentUser in the POST body; I'm not sure from the above curl output if that is the case.
And, this is the bit that actually fixed the issue:
(2) we had to also add the method name to the signature itself.
FYI we used this library: https://oauth.googlecode.com/svn/code/javascript/
But the tricky part, as you are seeing, was figuring out how to seed the method in that library that creates the signature. Without the 'method=currentUser' being part of the signature, we experienced the same error condition.
Check your timezone, date, and time on your computer. If any one of these is wrong, OAuth will fail.
Related
I'm generating a presigned URL on the server side of my application that looks like the following:
const s3 = new AWS.S3({
region: 'us-west-2',
signatureVersion: 'v4',
});
const params = {
Bucket: 'bucketName',
Key: fileName,
ContentType: 'text/csv',
Expires: 120
};
return s3.getSignedUrl('putObject', params);
Then I am trying to put the file into my S3 bucket using an ajax call that looks like this:
$.ajax({
url: url
type: 'PUT',
data: file,
processData: false,
contentType: 'text/csv',
success: function () {
console.log('Uploaded data successfully.');
},
error: function (xhr) {
console.log(xhr);
}
});
However, when I try to do this, I get a 403 Forbidden error and the XML says SignatureDoesNotMatch and The request signature we calculated does not match the signature you provided. Check your key and signing method.
I have made sure that the ContentType is the same for when I am generating the presigned URL AND when I am putting the file in the S3 Bucket. No matter what I do, nothing works and I still get this 403 error. I have tried to do binary/octet-stream for the ContentType and that didn't work. I tried to do ACL: 'public-read' and that didn't work. CORS is configured in my bucket as well so I know that isn't the issue (I had a different error for this). I did notice that in the Network calls, it says this:
Request URL: https://bucket-name.s3.us-west-2.amazonaws.com/fileName?Content-Type=text%2Fcsv&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ASIAXBWQUNDKKHHYM5GH%2F20210219%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20210219T015308Z&X-Amz-Expires=120&X-Amz-Security-Token=FwoGZXIvYXdzEIv%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaDOQ1EV3FIT00%2Fuo1BCKyAROysQ9G5PY9RFLeS8GwBLPEo7LCEJWstwki7nZatfddDczn0GKO7GwNEe5Qs%2BsLtMZv2xPTXo3Bwur%2BIhH7jV35HHQm976s1mOf8JZe2g%2BimUGNwLxBKY%2BrhWsN8yryNrd6k1VBRf1R9No9Jh%2FIumuwiVEoFLvVBHtILB9i53FdDo%2BJ8T%2BMCliV22SGBAwPQnYk8xvbo1%2B%2B%2B%2BAu%2FwVFl3tvG2yo7PHLzPpKqcpyJq4pMwko3aK8gQYyLUl0hZCTtit2cvBD5YAo57aMZBdTlpN5Wx3q27PSQZ1d8Bq1lQY%2BIQVkPlxZ%2Fw%3D%3D&X-Amz-Signature=446c16abde4d278c42c72373c85a6d44f959330468076e6bd888a8e2816b2b86&X-Amz-SignedHeaders=host
Request Method: PUT
Status Code: 403 Forbidden
Remote Address: 52.218.246.105:443
Referrer Policy: strict-origin-when-cross-origin
For Response Headers:
Referrer Policy: strict-origin-when-cross-origin
Access-Control-Allow-Methods: GET, PUT, POST, DELETE
Access-Control-Allow-Origin: *
Connection: close
Content-Type: application/xml
Date: Fri, 19 Feb 2021 01:53:09 GMT
Server: AmazonS3
Transfer-Encoding: chunked
Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
And Request Headers has Content-Type: text/csv... Not sure if this matters at all though
Any help will be greatly appreciated. I literally searched all over Google and nothing people said worked for me for some reason..
Adding answer because I cannot comment
Can you check why content-type isn't coming in your "X-Amz-Signed-Headers" along with "host"?
Since, that is part of "params" and therefore part of signature calculation, you should see
X-Amz-SignedHeaders=content-type%3Bhost
instead of ?Content-Type=text%2Fcsv
check your API key and secret, as SignatureDoesNotMatch error usually refers to the API key and secret mismatch, do refer to this previous answer:
https://stackoverflow.com/a/38837566/6687588
Turns out that something was wrong with my bucket, which is why I got this error. What exactly is different about the bucket I'm trying to write to is still unknown.. I tried another S3 bucket and it worked fine
I am trying to GET data with my client vueJS on port 8080 from the REST API on port 3000. This is resulting in a CORSE Error. A POST is working fine. To fix this I tried to create a proxy as described here https://medium.com/js-dojo/how-to-deal-with-cors-error-on-vue-cli-3-d78c024ce8d3.
//vue.config.js
module.exports={
devServer:{
proxy: {
'/teams': {
target: 'http://192.168.70.54:3000',
ws: true,
changeOrigin: true,
secure: false
}}}}
I want to redirect my traffic to the 3000 port.
//rest.js
function getTeams() {
var returnVal;
axios({
method: 'get',
url: REST_API + '/teams',
responseType: 'json'
})
.then(function (response) {
console.log(response.data); //Is what I want to return
returnVal = response.data;
});
console.log(returnVal); //Is undefined
return returnVal.data;
}
I am printing response.data to the console but my returnVal is always undefined. What am I missing?
This is my network log in the browser.
General:
Request URL: http://localhost:8080/teams
Request Method: GET
Status Code: 200 OK
Remote Address: 127.0.0.1:8080
Response Headers:
Referrer Policy: no-referrer-when-downgrade
access-control-allow-header: Origin, X-Request-With, Content-Type, Accept
access-control-allow-methods: GET, POST
access-control-allow-origin: *
connection: close
content-length: 1070
content-type: application/json
Date: Tue, 17 Dec 2019 18:57:14 GMT
Request Headers:
X-Powered-By: Express
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Host: localhost:8080
Referer: http://localhost:8080/setup
User-Agent: Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Raspbian Chromium/74.0.3729.157 Chrome/74.0.3729.157 Safari/537.36
There's a lot going on in this question.
Firstly, let's focus on this bit:
function getTeams() {
var returnVal;
axios({
method: 'get',
url: REST_API + '/teams',
responseType: 'json'
})
.then(function (response) {
console.log(response.data); //Is what I want to return
returnVal = response.data;
});
console.log(returnVal); //Is undefined
return returnVal.data;
}
The first log line is logging the correct value but the second log line is undefined.
This is to be expected. It has nothing to do with CORS or proxying.
The problem is that the axios request is asynchronous, so the then callback won't be called until some point in the future. By that point the function will have returned. You should find that the log lines are being logged in the 'wrong' order for the same reason.
You can't return an asynchronously retrieved value synchronously from a function. Using async/await may make it look like you can but even that is a fudge, hiding the underlying promises.
You have two options:
Return a promise from getTeams. That kicks the problem of waiting up to the calling code.
If you are inside a component you can set a data property inside the then callback. This is instead of returning a value.
Then we have the other parts of your question.
It would seem that you have successfully managed to configure a proxy. Difficult to be sure but from everything you've included in the question that seems to be working correctly. You wouldn't be getting the correct data in your console logging if the proxy wasn't working.
However, there are a lot of CORS headers in your response. If you're using a proxy then you don't need the CORS headers. A proxy is an alternative to CORS, you don't use both.
As for why your CORS request was failing prior to using a proxy, it's difficult to say from the information provided in the question.
I am running a local Springboot server, that when I access it locally in the browser, gives me a valid JSON object properly formatted (I verified this via JSON formatter).
I am also locally running a React application using node. I am attempting to use fetch() to get back that JSON object and running into issues. Finally got around CORs header issues, but not cannot figure out why the JSON object isn't coming back. Here's my code
var headers = new Headers();
headers.append("Content-type", "application/json;charset=UTF-8");
var myInit = { method: 'GET',
headers: headers,
mode: 'no-cors',
cache: 'default',
};
fetch(`http://localhost:3010/getJSON`, myInit)
.then(function(response){
console.log(response.data);
console.log(response);
console.log(JSON.parse(JSON.stringify(response)));
},function(error){
console.log(error);
});
So when I run this in Chrome with the debugger, the responses to the 3 log statements are:
1st logger
undefined
2nd logger
Response {type: "opaque", url: "", redirected: false, status: 0, ok: false,
…}
body
:
(...)
bodyUsed
:
false
headers
:
Headers {}
ok
:
false
redirected
:
false
status
:
0
statusText
:
""
type
:
"opaque"
url
:
""
__proto__
:
Response
3rd logger
{}
I have tried many different JSON parsing, stringify, etc, to no avail.
The next confusing part, is if within the Chrome debugger I go to the "Network" tab, click on the /getJSON, it shows me the entire JSON object just fine in both the "Preview" and "Response" tabs. So clearly Chrome is connecting to it correctly. Here's Chrome's "Headers" tab within "Network":
Request URL:http://localhost:3010/getJSON
Request Method:GET
Status Code:200
Remote Address:[::1]:3010
Referrer Policy:no-referrer-when-downgrade
Response Headers
view source
Content-Type:application/json;charset=UTF-8
Date:Thu, 12 Oct 2017 16:05:05 GMT
Transfer-Encoding:chunked
Request Headers
view source
Accept:*/*
Accept-Encoding:gzip, deflate, br
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Host:localhost:3010
Referer:http://localhost:3000/
User-Agent:Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
I have tried to mimic this header in my request, but not sure how it differs? Any help would be greatly appreciated as I am currently banging my head against the way with this!
You're getting an opaque response, which tells me that maybe you haven't completely resolved the cors headers situation. If you're fetching from the client, I would suggest proxying that through your nodejs so that instead of calling your springboot service, you call node, thus getting rid of the cors issues.
EDIT
You could create something like this:
import express from 'express';
import request from 'request';
const router = express.Router();
router.get('/proxyname', (req, res) => {
// Removing IPv4-mapped IPv6 address format, if present
const requestUrl = [your service's endpoint];
request(requestUrl, (err, apiResponse, body) => {
res.status(apiResponse.statusCode);
try {
res.json(JSON.parse(body));
} catch (e) {
res.send(body);
}
});
});
export default router;
and then on your nodejs server file, add it, like this:
import proxy from '[path to proxy file above]';
app.use('/path-to-endpoint', proxy);
and then call that from the client instead of your SpringBoot service.
I need to call an Office 365 Rest API from my own application.
When I copy and paste the url on the same browser session, I can see some XML.
If I paste that URL into an incognito window I get this error:
The custom error module does not recognize this error.
I am trying to make an API call to get that response from my application, when checking with developer tools, how they call the service I can see this:
As you can see the API call has some request headers.
Google chrome has the functionality to copy that as a CURL request.
And this works for me:
curl "https://portal.office.com/api/myapps/GetAllApps" -H "AjaxSessionKey: wEAjKvw1WCmLD27I2TGqAuga25rq5HdKrdEOCOTXhfX4k6H3U/AQru+hPWfWSMX0hhQ++OFkm/FvKN+Z1moC1Q=="
-H "Accept-Encoding: gzip, deflate, sdch, br" -H "X-SuiteServiceProxyOrigin: https://outlook.office365.com" -H "Accept-Language: en-US,en;q=0.8" -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36" -H "Content-Type: application/json;charset=UTF-8" -H "Accept: application/json" -H "Referer: https://portal.office.com/SuiteServiceProxy.aspx?upn=luis.valencia"%"40softwareestrategico.com&suiteServiceReturnUrl=https"%"3A"%"2F"%"2Foutlook.office365.com"%"2Fowa"%"2F&returnUrl=https"%"3A"%"2F"%"2Foutlook.office365.com"%"2Fowa"%"2F"
-H "Cookie: s.SessID=6bcb4983-767b-41b4-8bc9-03d5df23fab7; p.CachedJSFiles=16.00.1449.010:0x27F042160xD2810E3C0xF5EAFC860xA82B20870x58AB93C50x469628490xA2E1E0750xD5297DF50x63CBC2C30xF07895570x76AC56DF0xF515B60E0x052D52250xE77D86F40xD6CD36BB0xF5394BE50x0CA8EA080x810AC8B70xFFDEDE890x59EBF4680x117A18140xFCB544560x2E5289740x883529F50xA732E006; p.CachedCSSFiles=16.00.1449.010:0xAFCABDD50x7704885F0x1EC8288A0x2A2173270x7A142B580x630DEBB30x146543E00x49F2D68A0x9EA9D3370x8ED766C20xFD9BA3040xF4175814; p.UnAuthUserCookie=bb7622b1-75ba-49fe-ae48-feb7c77acba6; s.RPSClearCT=5j5ZGIOBjVgy5L8SUAexNuSViRkEHY5vXGshfJRnDOLJBGgtv9gbmBX03FDDg5hCygEMNgPp7JopPYGo9VtjKAjTXevaezBIVF0EE4HWxTKBpz7h+5G7ZHPNtwV3C3C27zp1XVbtPpA0tHyDzKnweUJtkPoBmQ2UeXpZYcGDAzVFExD8bZwk0RfNm4txuELilgX0Z+s7jRkh5dRu7MFaHH+naob4+2RJelaxcD7fBRGMT1kYloKJfgXihMfdRB09ZjT/egCmiT57jhGSTkIZfN4wIlAm2BzlQ4XBQ0kbLfG+bm/4m9OMITtQOf8Czj/8mlYzksaeGmVzf03syDlJgb4fYoDcMVQ4gUQBtLRZeaDhiIUQDBnTW70XHs4hpaHJCweSyfxrzvXzQSIg9NBe5a30he42cTaMDgY9XmzJxN5r1I32zAoYjN/gjdW4/q+zK+yeN3oNgHD8IufgUFEcdMCBa+CsgVPox9fqYlXJ0c25ksXgRTS6txYe0iHCwZlQgXLKslbjC7k1suHvE7jbCJ5pFfiwDxsISNegC26ENmNoVSXLVP3lwkvwnCMXywtMgiyP+hYjc30EI4inIC2pto9OhECztFscN46mCSBx/d/uTGMVJoSp3I6yikO522/UilLD7/eTeZj2/K0bwOJLVXeoHBNlcLb174JuKZI3KhmcMxFyuo3lWw3lE1YfWLDFqT5VE2eyX5ozk94xKtoWVOvf4MMEPPIMlQmu/gENl3GpegabsLdRr7MHQB16juRl2VS8yitoDrgp3H/d/9DyP8YTIDP3sF5Zdk2FWb/C+Avj6c9M3NR8WhO56rojCO0FkRnOo6uhDxNcVzRNulOs4+G7Sfgt9KOR7iYw3dEe6RrXccR3rp7wuHsdQfmqbbBq6/shW96m9tJuPPDIsYx7XmPU5TtvzFwOUkkLRcEbUd1MqwZknJVlHvbBc69nsc7dbBOQbJF07PfXyF064jjQDWQx0qWUoCRBHxoQNAv6i0lU1z0BTIm3JSU5ZsAZMzyWxzxZFVaJhXdZ861U0SQHfw4RTnQhvt8qjTrYDkmrvtEh8Ba/kPn7O7KpUMnODVRpCnCcIIC0BTNSdbAntlNHaA==; s.AjaxSessionKey=wEAjKvw1WCmLD27I2TGqAuga25rq5HdKrdEOCOTXhfX4k6H3U/AQru+hPWfWSMX0hhQ++OFkm/FvKN+Z1moC1Q==; s.userid=10037FFE9574B4FF; s.LoginUserTenantId=YSFQ8kyfSxMbyHdGGe3qeVi0Uug+6O1jT+ZVn5rXNvX9QvrR6VUpwYwG9HCZUaeyPZwzHuW/1zGwV179588ts2OVGQvmAo5Fvs07lM8ARoKOgyg7UxVdhvVsWU8cDWHiP4Is7P9PdSBPPoDQFjRTpg==; p.FirstLoginDateTimeUtc=id=-1406574579&value=Jan_27_2016; MUID=0F3BE9304DCA6D792017E0994C5A6C86; p.TenantCulture=f5b4bce5-06f0-4035-861f-ddea6d55a5e9::es-CO; s.TagCacheKey=fMdZZLwxq70P5SVbV794Vbf/Nb6nrvfWN+sIz3KSTqCAUfDP6dbCYDg6kiwPPZmjo0A8m48rtqF1Ir450dSxl9Y/qWu+a5gYRmTOZh0kXi8bndA40br4f+YO2xmVdZ3SpkSjwknoddE1meso8NTWvi/lL5+oKy5UOMB4B/YPRkunc7y6z0LWzq+xHgorBWo+ccL4JRzeTdThlxVDd23IcPO/w4O9+O51AHtw3qkZ7kvBiCZcooMX46yGP0SMnsZ0qjg8cv0o01w15/X7rdLQTTut7idyAsvhGsdlOLY8ghE=; s.BecContext=AAAAAQAAAAAEEGiA2yjQd8hDt7bHKBd5pSsGCWCGSAFlAwQCAQYJYIZIAWUDBAIBBglghkgBZQMEAQIEILiXEtiztm51j+9eensRmodQaco4fuQKKMwqb9FVtJxdBBDLmOAQDw0294WzUuRL6prcIIIBsJMrwukBvRsIudZmuuqrcO0I+DdJo5/fMTl+8zD3knXxHpckcUeBtdiqx/OPKiMF2i2gyqd7KV5p7E3yFPIsNs9UEf/A27qVOtZdvOh5YXX76MK0zjSN/19mSRLFu0sAdbIJ9OQhq8KVVx+55BGDRPp/LgZZfBvFG0nW0QSp4wioBCRyYdzBUFfPHnUyFsk2TzynImwDInjtrk3VAHXD2gojY9Hf7hL+16OXEeYGp4x20AAQV9ubRUwlEKZwt3tAfcw/RHq1lL6T+XbwijAqWQUFusHQ2Cm2jezy4tj6d8KxC4UJ1HFDdilKFPkefO4dprMFzPwAnGUHc2h2QPh+AsT5vvO5SQpyWaRy4lO5BK152jI+z60NMLsACkMn/WpopS0XsHph9fyYH4cq222bXUGnj977NN1YaQG90IHNVdoJ1Pbzl7MHD0QbStWky9hdFMzY4ZK2yO6X5KViSqbyLpIyDl315IoogL+8DQOHua+0GQrAE8z6vkSg0CMhbr+uGQCqbvDZ9tBFmRF6jbUQzAUbVoQoPPeynR+cNOT6B/8oS3zEhH9Ab/svAI1Qa5Fuvg==; s.LoginContext=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"
-H "Connection: keep-alive" --compressed
I can see some response as below:
Now I am trying to do the same with $ajax
$.ajax({
url: 'https://portal.office.com/api/myapps/GetAllApps',
type: 'GET',
dataType: 'json',
data: {
format: 'json'
},
beforeSend: function (xhr) {
xhr.setRequestHeader('Accept', 'application/json');
xhr.setRequestHeader('Accept-Encoding', 'gzip, deflate, sdch, br');
xhr.setRequestHeader('Accept-Language', 'en-US,en;q=0.8');
xhr.setRequestHeader('AjaxSessionKey', 'wEAjKvw1WCmLD27I2TGqAuga25rq5HdKrdEOCOTXhfX4k6H3U/AQru+hPWfWSMX0hhQ++OFkm/FvKN+Z1moC1Q==');
xhr.setRequestHeader('Connection', 'keep-alive');
xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
xhr.setRequestHeader('Cookie', 's.SessID=6bcb4983-767b-41b4-8bc9-03d5df23fab7; p.CachedJSFiles=16.00.1449.010:0x27F042160xD2810E3C0xF5EAFC860xA82B20870x58AB93C50x469628490xA2E1E0750xD5297DF50x63CBC2C30xF07895570x76AC56DF0xF515B60E0x052D52250xE77D86F40xD6CD36BB0xF5394BE50x0CA8EA080x810AC8B70xFFDEDE890x59EBF4680x117A18140xFCB544560x2E5289740x883529F50xA732E006; p.CachedCSSFiles=16.00.1449.010:0xAFCABDD50x7704885F0x1EC8288A0x2A2173270x7A142B580x630DEBB30x146543E00x49F2D68A0x9EA9D3370x8ED766C20xFD9BA3040xF4175814; p.UnAuthUserCookie=bb7622b1-75ba-49fe-ae48-feb7c77acba6; s.RPSClearCT=5j5ZGIOBjVgy5L8SUAexNuSViRkEHY5vXGshfJRnDOLJBGgtv9gbmBX03FDDg5hCygEMNgPp7JopPYGo9VtjKAjTXevaezBIVF0EE4HWxTKBpz7h+5G7ZHPNtwV3C3C27zp1XVbtPpA0tHyDzKnweUJtkPoBmQ2UeXpZYcGDAzVFExD8bZwk0RfNm4txuELilgX0Z+s7jRkh5dRu7MFaHH+naob4+2RJelaxcD7fBRGMT1kYloKJfgXihMfdRB09ZjT/egCmiT57jhGSTkIZfN4wIlAm2BzlQ4XBQ0kbLfG+bm/4m9OMITtQOf8Czj/8mlYzksaeGmVzf03syDlJgb4fYoDcMVQ4gUQBtLRZeaDhiIUQDBnTW70XHs4hpaHJCweSyfxrzvXzQSIg9NBe5a30he42cTaMDgY9XmzJxN5r1I32zAoYjN/gjdW4/q+zK+yeN3oNgHD8IufgUFEcdMCBa+CsgVPox9fqYlXJ0c25ksXgRTS6txYe0iHCwZlQgXLKslbjC7k1suHvE7jbCJ5pFfiwDxsISNegC26ENmNoVSXLVP3lwkvwnCMXywtMgiyP+hYjc30EI4inIC2pto9OhECztFscN46mCSBx/d/uTGMVJoSp3I6yikO522/UilLD7/eTeZj2/K0bwOJLVXeoHBNlcLb174JuKZI3KhmcMxFyuo3lWw3lE1YfWLDFqT5VE2eyX5ozk94xKtoWVOvf4MMEPPIMlQmu/gENl3GpegabsLdRr7MHQB16juRl2VS8yitoDrgp3H/d/9DyP8YTIDP3sF5Zdk2FWb/C+Avj6c9M3NR8WhO56rojCO0FkRnOo6uhDxNcVzRNulOs4+G7Sfgt9KOR7iYw3dEe6RrXccR3rp7wuHsdQfmqbbBq6/shW96m9tJuPPDIsYx7XmPU5TtvzFwOUkkLRcEbUd1MqwZknJVlHvbBc69nsc7dbBOQbJF07PfXyF064jjQDWQx0qWUoCRBHxoQNAv6i0lU1z0BTIm3JSU5ZsAZMzyWxzxZFVaJhXdZ861U0SQHfw4RTnQhvt8qjTrYDkmrvtEh8Ba/kPn7O7KpUMnODVRpCnCcIIC0BTNSdbAntlNHaA==; s.AjaxSessionKey=wEAjKvw1WCmLD27I2TGqAuga25rq5HdKrdEOCOTXhfX4k6H3U/AQru+hPWfWSMX0hhQ++OFkm/FvKN+Z1moC1Q==; s.userid=10037FFE9574B4FF; s.LoginUserTenantId=YSFQ8kyfSxMbyHdGGe3qeVi0Uug+6O1jT+ZVn5rXNvX9QvrR6VUpwYwG9HCZUaeyPZwzHuW/1zGwV179588ts2OVGQvmAo5Fvs07lM8ARoKOgyg7UxVdhvVsWU8cDWHiP4Is7P9PdSBPPoDQFjRTpg==; p.FirstLoginDateTimeUtc=id=-1406574579&value=Jan_27_2016; MUID=0F3BE9304DCA6D792017E0994C5A6C86; s.TagCacheKey=Tyo3H5iedT2v3VBQUIPR8X17RI2TPN7NbZ57l5cTNIu2XneEraxvGuohA6b+30tBn15x7XkXLKyjJjJSI7EX5f19nlvrpYcdHo8vRgCFjNVRaXFOqX5tjfVQ+3egiYh6xiKFxRK5RikgIhi+qHdUCgAAh3ubFGhsHdrqp4C9Z2vuKxNGGEIbytPAVslISKTRjlt8LrsaG0P8oqKIrLRgR0vFjbL3XZD5OV+38GpP+deHvLAJBc62HMpOrjqGcQF8FXZK9jRcAJrIgelXogXnINvqvmUTDHyn/l9JQTDoOUc=; p.TenantCulture=f5b4bce5-06f0-4035-861f-ddea6d55a5e9::es-CO; s.LoginContext=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; s.BecContext=AAAAAQAAAAAEEGiA2yjQd8hDt7bHKBd5pSsGCWCGSAFlAwQCAQYJYIZIAWUDBAIBBglghkgBZQMEAQIEIIimBSyEKl7CJv/2+fJ7kQWgf8ZFrE2rS5N4Q883AYGcBBDHkGvCyq58OtBctX3PiAbrIIIBsHHMMgDeIEwWcwFehoQJuPt6f1UvdJmidNryc/XXmTeGBKJn733KDzNXKjNmoREt/e59CGXSjpA97aD7b5Sjbjo9ubQ3gnFfykEZ5hePlMrbYgzNtMnRDpQ7UKIevkGU8K+REqUJPZqE4tcyi7gdnNXy/RlWfeaSGerL/6rZIm8OxTmtnIGCm7Hiw5CqLZ1PgCJuRDegh2VPJtI3s37pQC8o+81f02LOxQ2x/zV0BFH5dG9mLOGBomCEE5dgvMpjaE46mjK8jO9Z8JWzILVFS6H/ZxnW2ua9XJauMcgJrNjSTg6M+4ZEKbabDi0ACSdDTdekDJxN2edO0V4sLxNlTm7yyQJ1JLbcNlJWBJdrRS7GpXgl9n0byI/6GBDzTPHluqpQjirJ+2sFT7Y9ksetXDCE4VZTG6szx8igi1rc5vzyxWdfsc3rovUKMMNJM0aIXArMXYDN85C8K61X9gq+1iArr5fWGch+VwsVYWdXZANgYZDrnqknVLEJAbkd2Lrkd98kCMZluDWgH7ZDPN5lOxe7yRuFb+7vCmJXZMdgjiiPwuu1aZk8vXFNQNpxwJ8aTQ==');
xhr.setRequestHeader('X-KGP-DEVTYPE', 'xxx');
xhr.setRequestHeader('Host', 'portal.office.com');
xhr.setRequestHeader('Referer', 'https://portal.office.com/SuiteServiceProxy.aspx?upn=luis.valencia%40softwareestrategico.com&suiteServiceReturnUrl=https%3A%2F%2Foutlook.office365.com%2Fowa%2F%3Frealm%3Dsoftwareestrategico.com%26exsvurl%3D1%26ll-cc%3D1033%26modurl%3D0&returnUrl=https%3A%2F%2Foutlook.office365.com%2Fowa%2F%3Frealm%3Dsoftwareestrategico.com%26exsvurl%3D1%26ll-cc%3D1033%26modurl%3D0');
xhr.setRequestHeader('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36');
xhr.setRequestHeader('X-SuiteServiceProxyOrigin', 'https://outlook.office365.com');
},
success: function (data) {
alert(data);
},
error: function (xhr, status, error) {
var err = eval("(" + xhr.responseText + ")");
alert(err.Message);
},
complete: function (data) {
alert(data);
},
});
But I always get this error:
What am I missing in this code, to be able to call the service just as CURL and return me the response I need?
Answering your title question is just use the headers settings for $.ajax. For instance:
$.ajax({
url: 'https://portal.office.com/api/myapps/GetAllApps',
type: 'GET',
headers: {
'Accept': 'application/json',
'Accept-Encoding': 'gzip, deflate, sdch, br',...
}});
But I don't think that the error is caused because of missing headers. You should explain better the error, if is related with same-origin policy you should take a look on these links Working With and Around the Same-Origin Policy and Cross-Domain requests in Javascript).
I think you need to provide further information about this error but my first guess would be that the host has No 'Access-Control-Allow-Origin' enabled, and that's why you can do it from console.
You can try running chrome with --insecure or just install the allow-control-origin plugin
Can you try with by adding
dataType: 'jsonp',
crossDomain: true,
More information needs to be presented to confirm this, but jonystorm is most likely right. Browsers follow the same-origin policy. This means that all requests must be made with the same protocol, host, and port to succeed. The exception to this is if the requested server includes an Access-Control-Allow-Origin header. This header allows the server to explicitly list the other hosts that can make requests to it. You can read more about this on MDN.
My guess is that, although you're setting the cookie, your browser is not sending it with the request because it is not "credentialed". You should set it to use credentials with:
(...)
beforeSend: function (xhr) {
xhr.withCredentials = true; //Include this line
xhr.setRequestHeader('Accept', 'application/json');
(...)
The only issue is that this may not solve your problem entirely. Because by when doing CORS requests, your browser looks for the response header Access-Control-Allow-Origin if it does not match the exact host your page is hosted, the browser refuses to serve the answer to your page script. Even if the server returns the result with status code 200 OK
My guess is that Office 365 API wouldn't return this header with your exact host for security purposes. If it is your local/development use only, you can always run chrome disabling the Same Origin policy. This should circumvent the issue of having the browser refuse to serve you page the AJAX results.
I think the api requires authentication before api calls. You should be considering js api code samples instead of using curl type header with jQuery.
Try
1) https://www.itunity.com/article/calling-office-365-apis-jquery-adaljs-2758
2) http://paulryan.com.au/2015/unified-api-adal/
Or view office-365-api documentation for javascript (if provided by microsoft)
First off, I just wanted to say that I have read through all of the other threads relating to this topic, but haven't had any luck. Here's a breakdown of the issue:
Goals
Retrieve a CSRF token from Sails when the Ember Application starts
Inject that CSRF token into every AJAX request that is initiated from the Ember Application
To satisfy goal 1, I created an Ember Initializer that runs when the application first boots up (if there is a better place for this, I'm totally open to suggestions). To satisfy goal 2, I retrieve the CSRF token from Sails and then attempt to use Ember.$.ajaxSetup() to ensure the CSRF token is passed either as a header (X-CSRF-Token) or parameter (_csrf). I also ensure that I'm using the withCredentials option to ensure the cookie is set. Here's the code:
// initializers/csrf.js
import Ember from 'ember';
import config from '../config/environment';
export function initialize() {
Ember.$.get(config.APP.API_URL + '/csrfToken').then(function(result) {
Ember.$.ajaxSetup({
data: {
'_csrf': result._csrf
},
xhrFields: { withCredentials: true }
});
}, function(error) {
console.log(error);
});
}
export default {
name: 'csrf',
initialize: initialize
};
All of this appears to work as I can see in Chrome dev tools that the CSRF token is being retrieved and when I make an AJAX request, I see the data appended to the POST data or added as a header (tried both options). Here's the code I'm running and all of the associated headers:
Ember.$.post(config.APP.API_URL + '/auth/register', {
'email': _this.get('email'),
'password': _this.get('password')
}).then(function(response) {
console.log('It worked!');
});
Request Headers
POST /auth/register HTTP/1.1
Host: localhost:1337
Connection: keep-alive
Content-Length: 82
Accept: */*
Origin: http://localhost:4200
CSP: active
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.130 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
DNT: 1
Referer: http://localhost:4200/signup
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
Cookie: sails.sid=s%3AbrABhErTY3-ytTWOKFJ2KBj7DCAzaLDc.apD60Sd%2BW85GSbTfJ7E3B2PrUwnhOsW6GlNpZTu9jFg
Form Data
_csrf:yP7GDiU2-YGmLBfBvQtMPT3-hRpnfK0x-AfA
email:test#test.com
password:q1w2e3r4
Response Headers
HTTP/1.1 403 Forbidden
Vary: X-HTTP-Method-Override
Access-Control-Allow-Origin: http://localhost:4200
Access-Control-Allow-Credentials: true
Content-Type: text/html; charset=utf-8
Content-Length: 13
Date: Thu, 09 Jul 2015 08:11:34 GMT
Connection: keep-alive
As you can see from the Response headers, I end up receiving a 403 Forbidden - CSRF Mismatch from Sails. Now, here's where it gets a little weird: first, I'm able to run this just fine with Postman. I retrieve a token and then post that token along with the data to the /auth/register url and it works as expected.
I'm also tried removing the initializer and running the following code:
Ember.$.ajaxSetup({
xhrFields: { withCredentials: true }
});
Ember.$.get(config.APP.API_URL + '/csrfToken').then(function(result) {
Ember.$.post(config.APP.API_URL + '/auth/register', {
'email': _this.get('email'),
'password': _this.get('password'),
'_csrf': result._csrf
}).then(function(response) {
console.log('It worked!');
});
});
This works. However, at this point, I'm at somewhat of a loss as to what the issue actually is. Appreciate any help I can get.
Thanks in advance!
James
#jdixon04, Can you try URL-encoding the CSRF token before sending it through POST? The token mismatch will occur if the token is getting altered from the original.
I found this issue in Github: https://github.com/balderdashy/sails/issues/2266.
I hope this will solve your issue. Do try it and let me know if it works. Thanks.
#jdixon04, got here from your post on my github issue. Actually, isn't the CSRF token going to change at each request made to the server? Then you approach to fix the token when the frontend load cannot cope with this, you may have to fetch the token before each request and use ajaxPrefilter to pass it to the request.
Is that actually related to ember-data-sails? It seems to me you're doing pure ajax here! If you look in my config, you'll realise that pure ajax calls (for authentication as well) are exempted from csrf as I could not make it work as I wished :\ .
Add the x-csrf-token header like this:
Ember.$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': result._csrf
},
xhrFields: { withCredentials: true }
});