Skip to content

Using postMessage during embedded app authenticate

Hammad Khalid edited this page Jan 13, 2017 · 11 revisions

This guide will show you how to use the postMessage method to correctly redirect shops during the authentication process. This approach is already implemented in shopify_app gem v7.2.3. If you are already on this version, you are all set. If you are on an older version, and cannot upgrade, please read the guide below.

Merchants have to login to the app before it can be used. The first step of this process requires the merchant to authorize the app (give the app required permissions). This means that the app has to redirect to the authorization page (/auth/shopify?shop=myshopname). This is done in the #authenticate method of the shopify_app gem.

What needs to be updated?

Since embedded apps are loaded in an iframe, the iframe has to change the URL of the parent. We now have to use the postMessage method to change the URL when we are in an iframe. When we are not in an iframe, we can set the URL by changing location.href. This is typically done by returning inline javascript(#redirect_javascript in the shopify_app gem, which is called from #authenticate). Returning the following Javascript snippet covers both cases:

<script type='text/javascript'>
  // If the current window is the 'parent', change the URL by setting location.href
  if (window.top == window.self) {
    window.top.location.href = "/auth/shopify?shop=myshopname";

  // If the current window is the 'child', change the parent's URL with postMessage
  } else {
    message = JSON.stringify({
      message: "Shopify.API.remoteRedirect",
      data: { location: window.location.origin + "/auth/shopify?shop=myshopname" }
    });
    window.parent.postMessage(message, "https://myshopname.myshopify.com");
  }
</script>

How was this done before?

This was previously done by returning a page containing the following Javascript:

<script type='text/javascript'>
  window.top.location.href = '/auth/shopify?shop=myshopname';
</script>

What’s changing?

There was a change proposed in Chrome 56 (scheduled for release on Jan 31st, 2017) that would prevent iframes from changing the URL of their parents unless the iframe received a user gesture (e.g. user clicked on a button). After many bug reports, this change has been reverted from Chrome 56. They now show a deprecation warning instead.

The Chrome team wants to change this behavior to prevent malicious iframes from changing the URL without the user’s permission. While they have reverted the proposed change, they want to come up with a more permissive solution in Chrome 57 (scheduled for release on Mar 14th, 2017). The proposed solution will give iframes the ability to change the parent's URL if the iframe ever received a user gesture. Unfortunately, this will also break authentication.

Given these changes, we have to future proof authentication by using the postMessage method to change URLs from iframes.

Clone this wiki locally