19

I am loading an iFrame of a different domain. Both the parent and the iFrame sites are under my control. I'm using iFrame.postMessage to post messages to the iFrame. The site which I'm loading through the iFrame has a cookie(not a http only cookie). I need to read this cookie inside the parent site.

   var opIFrame=document.getElementById('opIFrame').contentWindow;

    /**
 * periodically invoking the Endpoint at OP for every six seconds
 */
setInterval(function(){
    console.log('Sending polling Request From RP Client ... ' + clientId);
    document.all.opIFrame.src = endPoint;
    opIFrame.postMessage(clientId,"https://localhost:9443/oauth2/loginstatus");
    var session=getCookieValue("session_state");
    console.log('**session**'+session);
},6000);


function getCookieValue(cookieName) {
var name = cookieName + "=";
var cookies =document.cookie.split(';');
if (!cookies) {
    return null;
}
for (var i = 0; i < cookies.length; i++) {
    var cookie = cookies[i].trim();
    if (cookie.indexOf(name) == 0) {
        return cookie.substring(name.length, cookie.length);
    }
}
return null;

}

I used the above methods to read the cookie. But it was not successful. Please advice me on this.

Updated Code:

<iframe id="opIFrame" style='visibility: hidden;' src=endpoint onload="getCookieValue('session_state')" >
</iframe> 
   <script>function getCookieValue(cookieName) {
        console.log("=====getCookieValue=======");
        var cookies = document.cookie;
        console.log("=====ALL cookies======="+cookies);
    }</script>

I'm getting empty array for cookies though I Can see the cookie in my browser.

Hasanthi
  • 1,251
  • 3
  • 14
  • 30
  • How are you listening to the message event on parent window? – Manik Arora May 06 '15 at 05:31
  • Yes Manik. I have already added an eventListner and to listen the response. But the problem is with accessing the cookie. I'm getting the response from iFrame on message event through the listener. Though I have a cookie named 'session_state' I am getting null when executing the getCookieValue(cookieName). – Hasanthi May 06 '15 at 05:58
  • Please see my updated answer and can you explain what you send in clientId ? Also I see that you are post the message to parent window before you read from the cookie is that intentional? – Manik Arora May 06 '15 at 06:48
  • You're doing it wrong, your trying to read cookie of iframe in parent window which is not accessible, its a browser security measure. Only the domain which created the cookie can read its cookie. So you have to read the cookie from within the iframe and then pass it to the parent window. If you don't have access or control over the page in the iframe then there is no way to get the cookie value. – Manik Arora May 06 '15 at 12:25
  • Yes Manik. I can post the cookie from iFrame to parent. But what I need is to read the cookie value of the iFrame from the parent. According to my specification I have to do it. But the parent and iFrame are in different domains. – Hasanthi May 07 '15 at 03:44
  • 1
    For this case I have only one solution for you - "It Is Not Possible". – Manik Arora May 07 '15 at 04:06

2 Answers2

9

This will give you the cookie of the iframe:

var cookie = document.getElementById("iframeId").contentDocument.cookie;

To get a cookie by name use this function (from stackoverflow):

function getCookie(cookie, name) {
    function escape(s) { return s.replace(/([.*+?\^${}()|\[\]\/\\])/g, '\\$1'); };
    var match = cookie.match(RegExp('(?:^|;\\s*)' + escape(name) + '=([^;]*)'));
    return match ? match[1] : null;
}
dsharew
  • 10,377
  • 6
  • 49
  • 75
6

I am not sure how are you catching the postMessage on the parent window or even catching or not, but below is the code that you should have on the parent window to catch the postMessage from the child iframe-

<script>
    window.addEventListener( "clientId",
      function (e) {
            if(e.origin !== 'https://localhost:9443'){ return; } 
            alert(e.data);
      },
      false);
</script>

UPDATE:
I replicated your scenario at my end and found that you should use-

document.cookie.split(';');
parent.postMessage(clientId,"https://localhost:9443/oauth2/loginstatus");

instead of-

opIFrame.cookie.split(';');
opIFrame.postMessage(clientId,"https://localhost:9443/oauth2/loginstatus");

Full Code
Parent Window: - http://localhost:8541

<div>
     <h1>Parent Window</h1>
     <iframe src="http://localhost:50761/parent/test" width="100" height="100"></iframe>
     <script>
         window.addEventListener("message",
         function (e) {
            if (e.origin !== 'http://localhost:50761') { return; }
               alert(e.data);
            },false);
     </script>
</div>

iFrame Page: - http://localhost:50761

<div>
    <h1>iFrame Window</h1>
    <script type="text/javascript">
        function createCookie(name, value, days) {
            if (days) {
                var date = new Date();
                date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
                var expires = "; expires=" + date.toGMTString();
            }
            else var expires = "";
            document.cookie = name + "=" + value + expires + "; path=/";
        }

        function readCookie(name) {
            var nameEQ = name + "=";
            var ca = document.cookie.split(';');
            for (var i = 0; i < ca.length; i++) {
                var c = ca[i];
                while (c.charAt(0) == ' ') c = c.substring(1, c.length);
                if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
            }
            return null;
        }
        createCookie('testCookie', "test content", 1);
        parent.postMessage(readCookie('testCookie'), "http://localhost:8541/");
    </script>
</div>

In the above code you can see I am accessing the cookie value in cross domain environment i.e. parent window is running on different domain and page loading in iframe is running on different domain.

I created a test cookie with test data in it and passed to the parent window using postMessage.

ozba
  • 6,522
  • 4
  • 33
  • 40
Manik Arora
  • 4,702
  • 1
  • 25
  • 48
  • I have done this part. The problem arises when accessing the cookie. – Hasanthi May 06 '15 at 05:59
  • I just need to pass a string as the client id. Through the code I have presented the post message to post the message to iframe, not to the parent. I mistakenly put opIFrame.postMessage instead of document. I changed it. But still I can't access the cookies in the iframe using the parent. – Hasanthi May 06 '15 at 09:49
  • You can only read the cookie of the iframe within the same iframe only and after reading you can pass the cookie value to the parent window using the postMessage. I can post the code for this if you want to see. – Manik Arora May 06 '15 at 10:14
  • I tried it by calling the getCookieValue function on iFrame load. But I could not access the cookie. Please put the code if you can. I have updated the question with my new code. – Hasanthi May 06 '15 at 11:49
  • Please see the updated answer I have added the full code now. – Manik Arora May 06 '15 at 12:21
  • 3
    Beware, according to [this](https://stackoverflow.com/a/4212964), your example, `http://localhost:8541` and `http://localhost:50761` would be the same domain! So, the same origin policy applies and you can access the cookie ... – Carlitos Way Mar 04 '20 at 22:54