I’m trying to implement the OAuth protocol so I can access the Shopify API as a third party API service in my Rails 6 app.
I’m able to get 3/4ths of the way through the OAuth process, but I can’t seem to make the POST request to send from my Rails app to Shopify. I’m new to Rails and backend development, so there could be a number of issues happening.
Right now, the code uses the shopify_api
gem to do it all. I’m not sure how to instantiate the session so that it’s referencing the same session across actions. I have a before_action
, which gets called each time that controller is used, regardless of action. So whenever it’s a new action, it creates a new session (I think that’s what is happening – I’m not sure if I’m using the correct language to describe this). I don’t know where to define the shopify_session
variable so that it’s valid across each action. Here is the code:
class ShopifyController < ApplicationController
before_action :shopify_session
def install
scope = ["write_orders,read_customers"]
permission_url = @shopify_session.create_permission_url(scope, "https://#{APP_URL}/shopify/auth")
redirect_to permission_url
end
def auth
token = @shopify_session.request_token(request.params)
end
private
def shopify_session
ShopifyAPI::Session.setup(api_key: API_KEY, secret: API_SECRET)
shop = request.params['shop']
@shopify_session = ShopifyAPI::Session.new(domain: "#{shop}", api_version: "2019-07", token: nil)
end
end
The code above returns:
ShopifyAPI::ValidationException in ShopifyController#auth
Invalid Signature: Possible malicious login
My ngrok log says:
POST /shopify/auth 500 Internal Server Error
GET /shopify/auth 200 OK
GET /shopify/install 302 Found
There might also be a CORS error. Browser header inspection says:
Referrer Policy: strict-origin-when-cross-origin
Additionally, it seems that it might be POSTing to itself, instead of sending the request to Shopify. I think that’s because in my view, I have the following code:
<%= button_to 'Confirm Account', shopify_auth_url %>
I don’t know how to trigger the POST request to send to Shopify…again, I’m new at Rails and backend — I mostly know frontend.
2
Answers
If anybody is struggling with implementing OAuth in Shopify, or attempting to work with outbound HTTP requests in Rails and happen to read this...
My lack of Rails knowledge was causing the problem. Turns out that I've been stuck on this for a month and a half, and it's been working the entire time. I was looking in my server logs and the network requests via my browser dev tools, expecting to find my app POST to Shopify. However, that POST is an outbound HTTP request and Rails only logs inbound requests. Additionally, the client's browser doesn't process that request, because the request is in the background, server-to-server (correct me if I'm wrong?).
I realized this by adding
puts token
aftertoken = @shopify_session.request_token(request.params)
, and discovered that I've been receiving the token this entire time. I should've done that at the very beginning -- a careless mishap and painful lesson learned. I used a gem called http_logger, which logs any outbound HTTP requests. If anybody knows a better way to access the outbound HTTP requests within a Rails controller (or anywhere), please let me know! Thanks.ps, here is more succinct version of my question: https://github.com/Shopify/shopify_api/issues/619
I think the problem is that you might want this Shopify auth logic in your ApplicationController so that it can be shared across all controllers.
Also, not sure what you’re doing with
shopify_auth_url
. Have you defined that route?