send a cookie with XMLHTTPRequest (TVMLJS)
Asked Answered
C

5

18

I am developing an application for my AppleTV. The App will read movies from an online website that hasn't developed any API for this kind of thing.

I use XMLHTTPRequest to get the different URLs and have the user search for his movie, etc... Everything is working fine, except for a single request. To get the movie URL, I have to send a get request to a specific address (let's say http://example.com/getmovie.html) with a constant cookie (let's say mycookie=cookie).

I've tried using setRequestHeader:

var xhr = new XMLHttpRequest();
xhr.open("GET", url, false);
xhr.withCredentials = true;
xhr.setRequestHeader('Cookie', 'mycookie=cookie');
xhr.send();

But no cookie seems to be sent. I also tried setting the cookie with Document.cookie like I would have probably done in a "normal" js script (running in my browser) but no luck either.

This is extremely frustrating, especially since I'm stuck so close to the end of my app.

I guess cross-origin might be the issue but I'm able to get URLs without issues if I don't have to set cookies, so I am a bit lost there.

Please let me know how I can get http://example.com/getmovie.html with a specific cookie header.

Thanks for your help

Child answered 15/2, 2017 at 22:0 Comment(7)
im sorry to inform you but the xmlHTTPRequest function of javascript does not allow a cookie header to be set for security reasons as shown here: #15198731 the best way i could see you making that get request would be to a proxy server that you would be runningNeptunium
Thanks. Is there an other way to execute a get request to an url with a cookie then ? Maybe using something else than xmlHTTPRequest ? This security really seems like an overkill... From what I saw on other posts, I thought the security was coming from the browser. But in my case there are no browser, since it is an appleTV app.Child
it is probably built into the xmlhttprequest specification and if you have control of the server you are sending the request to and are able to modify response headers it may be possible to make an xmlhttp request with a cookieNeptunium
Sadly I don't have control over the server I'm sending the request to... I find it very strange that I cannot send a cookie with javascript, especially since sending a forged cookie with a browser is so easy (inspect the element/network/modify and resent the request/add your cookie). If sending an arbitrary cookie really was a security issue, that wouldn't be possible (or the whole internet would have a huge problem right now ^^), so it would really surprise me if there was no solution to my problem. Thank you for taking the time to answer my question :)Child
no problem, but i think that the reason that you can not send cookies with javascript isnt to prevent you from sending forged cookies on machines you control, but instead to prevent you from placing javascript on your own website that would allow you to set cookies on other people's machines for domains you don't own. so for example lets say you were running a blog that on every page in the background would make an xmlhttprequest to a competitor's blog with an incorrect session cookie which would effectively log people out of the competitors site. if possible can i write an answer for points?Neptunium
Well that makes sense... of course you did provide me with an answer (even if it isn't the one I was hoping for sadly) ! I still hope someone will come up with a magic way so send cookie (maybe not using xmlhttprequest) but you deserve your points :)Child
What Mohammad described is basically a CSRF (Cross Site Request Forgery) attack. You can find more information here: owasp.org/www-community/attacks/csrfNidorf
N
15

im sorry to inform you but the xmlHTTPRequest function of javascript does not allow a cookie header to be set for security reasons as shown here: Why cookies and set-cookie headers can't be set while making xmlhttprequest using setRequestHeader? the best way i could see you making that get request would be to a proxy server that you would be running. I believe that it is built this way to prevent you from setting cookies on domains that you do not own, furthermore i do not see an alternate resolution to this problem as no were in the docs i looked at was cookie persistence or management mentioned

Neptunium answered 15/2, 2017 at 23:25 Comment(0)
M
7

Well... the problem here is the line xhr.setRequestHeader('Cookie', 'mycookie=cookie'); line just because the 'Cookie' header is reserved for the client browser to send the stored cookies. This means you are trying to do what the browser already does. When you send a any request, the client browser automatlycally will take all the cookies related to the site you are requesting and put them on the 'Cookie' header, you don't need to do anything else, if your cookie exist in your browser, it will be send.

Missionary answered 30/9, 2019 at 18:26 Comment(4)
You're wrong, XMLHttpRequest does not put the cookies related to the requested site into Cookie header. At least this is not the default behaviorVitta
I didn't said XMLHttpRequest add the Cookie header by itself, but the browser does: developer.mozilla.org/en-US/docs/Web/HTTP/…Missionary
The browser does not do this either. It would be a security breach if it did so. I recommend to remove your answer because it is misleading and wrongVitta
@Vitta I'm sorry, but that is wrong, withCredentials were clearly set in the question, enabling cookies (and authorization headers) no matter which site. For same-site, cookies are always set. For other domains, you need to set withCredentials to true on the XHR object (as well as take care of CORS on the server side).Smoothie
C
5

In case someone has the same issue:

I didn't find a solution to sending a cookie with javascript. However, in my situation, the origin of the request didn't matter, only the cookie did. My solution was then to create a PHP file receiving the destination URL and the cookie content as parameters, and then sending the get request with the cookie as a request header. (more information about how to do so here: PHP GET Request, sending headers).

In my javascript I then use XMLHttpRequest to connect to my PHP file (hosted online) with simple get parameters and I then receive the response from the PHP. That trick of course won't work if the origin of the request matters (except if you host your file at home I guess, but in my case I want my application to work even if my WAMP isn't on).

Child answered 16/2, 2017 at 12:56 Comment(0)
I
3

Cordova how to send session cookie, allow credentials with XMLhttprequest:

// JS
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://example.com/ajax.php', true);
xhr.withCredentials = true;
xhr.onreadystatechange = function() {
    if(xhr.readyState == 4 && xhr.status == 200) {
        // alert(xhr.responseText);
        // Get header from php server request if you want for something
        var cookie = xhr.getResponseHeader("Cookie");
        // alert("Cookie: " + cookie);
    }
}
xhr.send();

// Php 
// You can add cookie to header and get with (session works without it) 
header('Cookie: PHPSESSID='.$_COOKIE['PHPSESSID']);
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: Origin, Content-Type, Accept, Authorization, X-Request-With, Set-Cookie, Cookie, Bearer');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 86400');
Intemerate answered 18/7, 2018 at 7:20 Comment(0)
O
1

Can be solved by adding xhr.withCredentials = true;

Opal answered 18/9, 2023 at 8:2 Comment(1)
This works when the client browser already has the cookie, and the intent is to get the xhr to include the cookie as part of the request.Warhead

© 2022 - 2024 — McMap. All rights reserved.