I have a Rails application that is set to receive a webhook from WooCommerce. Specifically I am looking for when an order is created. I have tested and verified that it works when I have protect_from_forgery except create. Now I am trying to secure my application by verify the webhook. WooCommerce’s documentation states the following secret is passed in the request header:
secret: an optional secret key that is used to generate a HMAC-SHA256 hash of the request body so the receiver can verify authenticity of the web hook
At the moment I am not sure how I am suppose to verify the request, then act on it. And if the request is not authorized reject it with a 401. Here is what I am trying:
class HooksController < ApplicationController
protect_from_forgery
before_action :restrict_access
def order_created_callback
...
end
private
SHARED_SECRET = 'my_secret_key'
def verify_webhook(data, hmac_header)
digest = OpenSSL::Digest::Digest.new('sha256')
calculated_hmac = Base64.encode64(OpenSSL::HMAC.digest(digest, SHARED_SECRET, data)).strip
calculated_hmac == hmac_header
end
def restrict_access
data = request.body.read
verified = verify_webhook(data, env["X-WC-Webhook-Signature"])
head :unauthorized unless verified
end
end
But so far I have been unsuccessful. Any input would be greatly appreciated. Thanks.
Ok I figured out the issue I was having. In case anyone else is trying to work with WooCommerce web hook it seems my issue was appropriately grabbing the header file of the request to match it against my calculated HMAC.