1
votes

I set up shopify auth (omniauth-shopify-oauth2 gem) for my rails 3.2.6 app.

It works fine when routed from a web page (to the following controller#action)

class ShopifyController < ApplicationController
  ...
  def login
    redirect_to "/auth/shopify?shop=#{current_retailer.primary_host_name}"
  end

It redirects me to shop login and, once I am logged in, redirects back to success callback. All good (see SERVER LOG SUCCESS below).

But when I try to do pretty much the same from the rails console:

irb(main):001:0> RestClient.get 'http://localhost:3000/auth/shopify?shop=vinehillposters.myshopify.com'

I get:

RestClient::Unauthorized: 401 Unauthorized: <?xml version="1.0" encoding="UTF-8"?>
<hash>
  <errors>[API] Invalid API key or access token (unrecognized login or wrong password)</errors>
</hash>

see SERVER LOG FAIL below


SERVER LOG SUCCESS:

Processing by ShopifyController#login as HTML
... AR stuff snipped ...
Redirected to http://localhost:3000/auth/shopify?shop=vinehillposters.myshopify.com
Completed 302 Found in 93ms (ActiveRecord: 1.6ms)
(shopify) Setup endpoint detected, running now.
(shopify) Request phase initiated.
"https://vinehillposters.myshopify.com/admin/oauth/authorize?response_type=code&client_id=44dd9799fbc268c36ef609f0c2386b8c&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauth%2Fshopify%2Fcallba
ck&scope=read_orders"

Started GET "/auth/shopify?shop=vinehillposters.myshopify.com" for 127.0.0.1 at 2012-10-30 11:24:21 +0000
(shopify) Setup endpoint detected, running now.
(shopify) Callback phase initiated.

Started GET "/auth/shopify/callback?code=c8c6696ed347e37324d2d62ec203457b&shop=vinehillposters.myshopify.com&timestamp=1351596261&signature=e6324b041d6a6ed1e07719a8909d70f7" for 127.0.0.1 at 
2012-10-30 11:24:21 +0000
Processing by ShopifyController#auth_callback as HTML
...


SERVER LOG FAILURE:

(shopify) Setup endpoint detected, running now.
(shopify) Request phase initiated.
"https://vinehillposters.myshopify.com/admin/oauth/authorize?response_type=code&client_id=44dd9799fbc268c36ef609f0c2386b8c&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauth%2Fshopify%2Fcallback&scope=read_orders"


Started GET "/auth/shopify?shop=vinehillposters.myshopify.com" for 127.0.0.1 at 2012-10-30 11:24:54 +0000

You may have noticed that I print out the request_phase url right before it gets redirected to shopify (after (shopify) Request phase initiated.). It is the same in both cases. Except in one case it returns success and in another it is 401.

So, what am I doing wrong?

1
What are some other things the browser could be doing that you aren't with RestClient? Could it be something related to cookies? - csaunders
Most certainly. But I am supposed to be able to do without it. github.com/Shopify/shopify_api - artemave
Especially if I need to trigger shopify auth from a background job or something - artemave
You get a token from the Callback in your omniauth.auth environment variable. Store the token in the database for that shop or whatever then use that to prepare your authenticated session with Shopify. - csaunders
@csaunders just figured that! I was mixing installation (something you do once) with authentication (something you do when you use API) - artemave

1 Answers

2
votes

I think your question is confusing and you are focusing on the wrong part. What you need to do is once your user has logged in grab some information about them from the shopify callback.

def shopify
  shopify_domain = params[:shop]
  @your_shop_object = your_finds_or_initializes_shop_or_auth_object_with shopify_domain, token

  if @your_shop_object.persisted?
    redirect_to root_url
  else
    # something went wrong :/
    session['devise.shopify_data'] = request.env['omniauth.auth']
    redirect_to auth_index_url
  end
end

private
def token
  request.env['omniauth.auth']['credentials']['token']
end

Now with this you can use that persisted shop objects data to set up an authorized session

session = ShopifyAPI::Session.new(domain, authentication_token)
if session.valid?
  ShopifyAPI::Base.activate_session(session)
  # Now you can make api calls for that shop (domain)
else
  Rails.logger.error "[Shop] Could not create a valid session for '#{domain}'"
end