ℹ️ Important
If the date doesn’t make it evident, this is an old post. In the intervening years, Shopify has made a lot of changes, including a recent heavy overhaul. I’m leaving this up for posterity, but I don’t know or guarantee that it still works in light of those changes.
I get the pleasure of writing integration after integration to Shopify at my day job. As a result, I have become quite familiar with their documentation and its gaps. The HMAC verification piece of the OAuth/embedded app installation process is a particularly glaring gap. So let’s close it.
What’s Wrong With The Docs?
If you’re a Ruby developer, probably not much. Shopify’s got a nice little Ruby gem that does a great deal of the work for you. Happy days!
But for a PHP developer like myself? Well…the docs look pretty much like this:
- Create an app in the dashboard
- Add the redirect code
- ????
- Profit!
What’s even worse, is that one of the few libraries and step-by-step PHP examples are both wrong in how they do HMAC verification! (The fact that that guide is on Shopify, proper, is astounding to me.)
Okay, so that entire section is in dire need of a good tutorial for those not blessed with Ruby. I’ll get to that in the near future. In the meantime, I want to have out there the correct way of doing HMAC verification.
The Right Way
The documentation does actually give us the information on how to correctly generate the HMAC value, but it does so in a language-agnostic way (which is all well and good, but requires quite a bit of fiddling to get it right).
They can be summarized as follows:
- Pull everything from the request except the HMAC and signature fields
- Sort remaining items lexilogically
- Replace special characters in keys and values
- Hash per HMAC standards with the shared secret (query string, SHA256)
If done properly, the generate string should match the HMAC field Shopify sent.
Now, what’s that look like in PHP? Pretty simple, thankfully:
If you happen to be running Laravel, you can clean it up a little, like this:
How does this differ from the other ways? For the most part, the fatal error in the available examples is that they do step 1 (of all things) backwards. Instead of taking the request and removing the keys that need removed, they all built an array from the keys in the example code in the documentation. This was all well and good while the response from Shopify matched the documentation, but as soon as they changed that response, well…everything broke.
But, now you have it! The right way to do Shopify’s HMAC verification. In the near future, I’ll be writing up a tutorial on how to painlessly set up a Shopify embedded app in PHP.