I'm trying to use the cloudapp api with javascript, the problem is that the api is using Digest access authentication for authentication.
I visited the app documentation but there is no examples or wrappers for javascript.
I tried many things but here is my latest code:
$.ajax({
headers: { "Accept": "application/json"},
type: "GET",
url: "http://my.cl.ly/account",
crossDomain: true,
success:function(data, textStatus, request){
console.log(data);
}
});
All I'm getting with this code is Cross-origin resource sharing (CORS) problems and a 401 Unauthorized error.
here is the response headers:
Cache-Control no-cache
Connection keep-alive
Content-Type text/plain; charset=utf-8
Date Wed, 17 Sep 2014 20:15:26 GMT
Transfer-Encoding chunked
WWW-Authenticate Digest realm="Application", qop="auth", algorithm=MD5, nonce="MTQxMDk4NDkyNjo4MmE4ZWU0ZDY4YWUwYTAyMjRjNzIzYWU2NzE5YTQyMQ==", opaque="9eb56ccb2e8b017ae42bdb4739690863"
X-Request-Id b6bdbf12-f1d9-4769-a06d-216d5d7ae669
X-Runtime 0.008105
status 401 Unauthorized
x-ua-compatible IE=Edge,chrome=1
So how can I use the WWW-Authenticate to authenticate and retrieve data?
Also I tried adding
xhrFields: {
withCredentials: true
}
I got a promt, I filled it and now I'm getting 200 OK status but no response.
All I need is to get this working and getting a return.
Thanks.
It looks like you're using Digest Access Authentication algorithm. Getting 401 on your first request is a part of algorithm, you have to implement it completely. In WWW-Authenticate header you've got all required fields. I hope this will help you:
http://en.wikipedia.org/wiki/Digest_access_authentication
What is digest authentication?
Related
We have an AWS Lambda API server that is placed behind an APIGateway endpoint, and a React.js client that lives in an S3 bucket and served through Cloudfront.
When the user logs in the API server sends a cookie in the Set-Cookie header, but the browser doesn't send it back in subsequent requests. We've tried it on Chrome 90 and the latest Firefox, but no dice.
After log-in, the React code does a fetch like this:
fetch(`${url}/api/<blahblah>`, {
method: 'GET',
credentials: 'include',
headers: new Headers({
accept: 'application/json'
})
But the browser appears to decide that the cookie doesn't match and so doesn't send it in the request.
I have tried all manner of flags in the Set-Cookie, and the browsers are happy to store it with the initial response.
Currently the cookie looks like this:
<cookie contents>; Expires=Fri, 21 May 2021 12:00:32 GMT; Max-Age=86400; HttpOnly; Path=/; SameSite=Lax
Although I have tried setting the domain explicitly, setting the Secure flag with SameSite=None, removing the HttpOnly flag, and probably a dozen other combinations. The browsers all say that the cookie is valid, with no warnings or anything. Both the frontend and backend are using HTTPS, so Secure; SameSite=None should work, right?
The response headers from the server include access-control-allow-credentials: true, and access-control-allow-origin is set to the right Cloudfront URL.
I have had it working once on a localhost to localhost request, but even that doesn't seem to work any more.
What have I missed? Is it an AWS setting that needs changing? Is it the fetch call that is missing an option?
This question already has answers here:
Trying to use fetch and pass in mode: no-cors
(9 answers)
Closed 4 years ago.
In a ReactJS Component, a fetch call to an API that redirects to another API won't return the final destination's response. Fetch simply returns opaque response with null 0 etc as if your call failed. It doesn't even say it redirected. But in Chrome's console, the Network tab clearly showed the redirected call succeeded.
let call = fetch(encodedQueryUrl, {
method: 'GET',
cache: 'no-cache',
mode: 'no-cors',
redirect: 'follow',
credentials: 'same-origin'
}).then((response) => {
console.log("Response???", response);
return response;
});
So encodedQueryURL Response Headers:
Request Method: GET
Status Code: 302
Referrer Policy: no-referrer-when-downgrade
Access-Control-Allow-Headers: access-control-allow-origin
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE
Access-Control-Allow-Origin: *
content-length: 0
content-type: text/html; charset=UTF-8
And the 302 Response headers:
Request Method: GET
Status Code: 200
Referrer Policy: no-referrer-when-downgrade
Access-Control-Allow-Headers: access-control-allow-origin
access-control-allow-methods: GET, POST, GET, OPTIONS, PUT, DELETE
access-control-allow-origin: *
content-type: application/json; charset=UTF-8
Because you're using mode: no-cors, you're obtaining an opaque response. This happens as a security mechanism, because you're avoiding CORS validation. So, to make it secure, the content of the response is not accessible from JS code, it only can be used for caching purpose.
UPDATE: As I can understand, probably you used no-cors because you're having issues with CORS, as you said, because you're consuming the resource from another domain, different to the domain of the API.
For achieving this, you will need either to:
Modify your API to add the domain in which your frontend app is running, to the list of approved origins so you are able to consume the API or
Having your frontend app running in the same server as your API
I've done all kind of searching and can't seem to figure this one out.
I'm trying to create a widget that you can put on any website to get feedback from users, which will post the feedback to my app at waterloo.herokuapp.com where users can log in to see all of their feedback.
I'm using a jquery ajax POST method to my Rails app with the following code:
fb_form.submit(function(ev) {
$.ajax({
type: 'POST',
url: 'http://waterloo.herokuapp.com/domains/2/comments',
data: fb_form.serialize(),
success: function(data) {
console.log(data);
alert('cool, this worked');
$('.feedback-container').hide();
},
error: function(data) {
console.log(data);
}
});
and I'm getting the following error:
XMLHttpRequest cannot load http://waterloo.herokuapp.com/domains/2/comments. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://www.will-wallace.com' is therefore not allowed access.
In my comments_controller, I have a set_headers before_filter which should allow a post from any domain (and works locally):
def set_headers
headers['Access-Control-Allow-Origin'] = '*'
headers['Access-Control-Expose-Headers'] = 'Etag'
headers['Access-Control-Allow-Methods'] = 'POST'
headers['Access-Control-Allow-Headers'] = '*, x-requested-with, Content-Type, If- Modified-Since, If-None-Match'
headers['Access-Control-Max-Age'] = '86400'
end
The weirdest thing is, when I log in to see the feedback that I was attempting to post, it actually succeeded. Nonetheless, I am getting an ajax error response as I mentioned before.
The domain I'm testing the widget on is will-wallace.com, if it helps at all to go and actually fiddle around with it.
Lastly, if it helps at all, I seem to be getting a 500 error by tailing the heroku logs:
2014-07-10T01:39:59.624512+00:00 heroku[router]: at=info method=POST path="/domains/2/comments" host=waterloo.herokuapp.com fwd="96.255.218.195" dyno=web.1 connect=5ms service=63ms status=500 bytes=1543
Looking at your website, when I use the widget I see the same error message in the console:
XMLHttpRequest cannot load http://waterloo.herokuapp.com/domains/2/comments. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://www.will-wallace.com' is therefore not allowed access.
But if you look at the actual response, its getting a 500 error from the server:
HTTP/1.1 500 Internal Server Error
Content-Type: text/html; charset=utf-8
Date: Thu, 10 Jul 2014 02:40:45 GMT
Server: WEBrick/1.3.1 (Ruby/1.9.3/2014-05-14)
X-Request-Id: 66b02889-e2e9-4cac-b38f-3e5370982b55
X-Runtime: 0.052554
Content-Length: 1266
Connection: keep-alive
This is a bit misleading. It looks like you are setting your headers correctly, but since your server is getting an error, it either never gets to that code or ignores custom headers on errors. If you Fix your 500 error, you should see your Access-Control headers start showing up in the response.
On a sided note, WEBrick isn't the best server for production, best for development mode only.
I am having an issue getting cross origin resource sharing working with cookies. Here is my setup:
Client:
$.ajax({
type: 'POST',
url: '/processReq',
data: params,
xhrFields: {withCredentials:true},
crossDomain: true,
success: ...
});
I have debugged the client in the browser, and have verified that XMLHttpRequest.withCredentials is in fact true.
Server:
I am setting the following headers:
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Origin', '*');
My issue is that I cannot get the session cookie to be stored by the browser, and sent on a subsequent request to the server.
Here are the response headers in the browser:
{
"server": "nginx/1.2.6",
"date": "Fri, 01 Feb 2013 23:46:07 GMT",
"content-type": "application/json; charset=utf-8",
"content-length": "306",
"connection": "keep-alive",
"x-powered-by": "Express",
"access-control-allow-credentials": "true",
"access-control-allow-origin": "*",
"set-cookie": [
"id=s%3Azm1m...NXe4Lkr9rLw; Domain=api.mydomain.io; Path=/; Expires=Sat, 01 Feb 2014 23:46:07 GMT; HttpOnly"
]
}
Every time I test, I do not get a cookie sent to the server. Am I missing something? Any help is much appreciated.
You cannot use ('Access-Control-Allow-Origin', '*') with ('Access-Control-Allow-Credentials', true). You need to explicitly set the Access-Control-Allow-Origin to one value. If you still want the '*' behavior, set the value to the requests origin header programatically.
From https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS?redirectlocale=en-US&redirectslug=HTTP_access_control :
Important note: when responding to a credentialed request, server
must specify a domain, and cannot use wild carding.
Another elegant option that side-steps CORS altogether is using a hidden iframe and window.postMessage.
The postMessage API let's two browser frames communicate cross-domain. The basic design is as follows:
load main page on domain-1.com
main page loads hidden iframe from domain-2.com
hidden iframe loads javascript to interface with domain-2.com APIs
Any time the main page wishes to talk cross-domain, it proxies the request through the hidden iframe. There is no CORS to deal with — none!
A Few Tutorials:
http://davidwalsh.name/window-postmessage
https://developer.mozilla.org/en-US/docs/DOM/window.postMessage
Exactly what the title suggests:
I perform an ajax request to my server, it responds with a 403 but there are headers I want to retrieve and save on localStorage. This is for a phonegap app (Android and iOS), so the initiating domain isLocal (file://). When performing the call, I use the following code to try to intercept the response, but it returns undefined or an empty string.
Ajax:
$.ajax({
url: serverLink+action,
type: "POST",
data: "access_token="+accessToken+"&uid="+uid,
crossDomain: true,
complete: function(resp){
var header = resp.getAllResponseHeaders();
var match = header.match(/(Set-Cookie|set-cookie): (.+?);/);
if (match) session = match[2];
console.log(header, session)
}
})
Response Headers
Connection Keep-Alive
Content-Encoding gzip
Content-Length 1198
Content-Type text/html
Date Fri, 13 Apr 2012 22:51:02 GMT
Keep-Alive timeout=15, max=100
Server Apache/2.2.14 (Ubuntu)
Set-Cookie sessionid=ebd26167e32bada2d2ed0bd3cc16d8a2; expires=Fri, 27-Apr-2012 22:51:02 GMT; Max-Age=1209600; Path=/
Vary Cookie,Accept-Encoding
Further reading led me to here, which speaks of the CSRF on a django server. We are using a django server and either this or the 403 is the problem I suspect. There doesn't seem to be a way (from the example answer there) to collect the cookie from webview and send it back to the server on subsequent requests.
use the jquery XHR object which as a method getAllResponseHeaders() which should provide what you are after.
http://api.jquery.com/jQuery.ajax/
This problem was most definitely caused by CSRF protection on the django server. Disabling or implementing workarounds as per django is the only way around this.
Actually this post helped tremendously: Django CSRF check failing with an Ajax POST request