【问题标题】:Switch provider for the omniauth-shopify-oauth2 gem in runtime?在运行时为omniauth-shopify-oauth2 gem 切换提供程序?
【发布时间】:2018-11-16 05:40:17
【问题描述】:

omniauth-shopify-oauth2 gem 的初始化程序应该如下所示:

# config/initializers/omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
  provider :shopify, ENV['SHOPIFY_API_KEY'], ENV['SHOPIFY_SHARED_SECRET']
end

但是,在我们的 Rails 应用中,有几个不同的品牌提供相同的功能。在整个应用程序中,请求的request.domain 决定了您所接触的品牌(brand1.example.combrand2.example.com 等)。

我们可以轻松存储品牌特定的凭据并将用户重定向到品牌特定的授权路径:

https://example.myshopify.com/admin/oauth/authorize?client_id=brand1&scope=read_orders,read_products&redirect_uri=https://brand1.example.com/auth/shopify/callback

但我不知道如何根据访问过的request.domain 选择不同的中间件提供商。知道如何设置吗?

【问题讨论】:

    标签: ruby-on-rails oauth oauth-2.0 shopify omniauth


    【解决方案1】:

    Omniauth 提供有关 Dynamic Providers 的文档,这将在此处有所帮助。比如:

    # config/initializers/omniauth.rb
    Rails.application.config.middleware.use OmniAuth::Builder do
      provider :shopify, setup: lambda do |env|
    
        # Do logic to get correct credentials for request.
        # For example, if you store the credentials on a model called Brand,
        # and have it keyed on "subdomain":
        request = ActionDispatch::Request.new(env)
        brand = Brand.find_by(subdomain: request.subdomain)
    
        env['omniauth.strategy'].options.merge!({
          client_id: brand.client_id,
          client_secret: brand.client_secret
        })
    
        # `site` needs to be set. This is part of the shopify provider setup phase, which we are overriding
        env['omniauth.strategy'].options[:client_options][:site] = "https://#{ request.GET['shop'] }"
      end
    end
    

    【讨论】:

    • 感谢您让我关注动态提供商。但我认为我需要更彻底的演练。我将上述代码放在哪里,以及如何在不全局更改提供程序的情况下基于会话(例如在控制器中)处理它?
    • @JohnSmith1976:此代码进入初始化程序并替换您在问题中提供的provider sn-p。然后,获取品牌特定值的逻辑位于 lambda 中,而不是任何控制器中(尽管您可能希望将此逻辑提取到 PORO 以便更好地组织代码和简化测试)。我已经更新了这个例子,希望它更清楚。
    • 谢谢@gwcodes 我已经测试过了,它看起来很有希望。然而,我并没有完全理解,因为在lib/omniauth/strategies/shopify.rb:93 处引发了异常。 options[:client_options][:site] 似乎为零。似乎this SO post 可能会解决这个问题,但我不确定?
    • @JohnSmith1976:尝试将site: "https://#{request.GET['shop']}" 添加到哈希中(例如在client_secret 下)
    • 完美,这让我朝着正确的方向前进。我添加了这些行:params = Rack::Utils.parse_query(env['QUERY_STRING'])env['omniauth.strategy'].options[:client_options][:site] = "https://#{params['shop']}"。然后它起作用了。如果您同意这一点,请相应地更新答案以供其他人使用,然后我将确保检查答案并释放赏金。再次感谢您的帮助!
    猜你喜欢
    • 2014-12-10
    • 1970-01-01
    • 2012-06-29
    • 2011-11-04
    • 2012-07-11
    • 2012-07-27
    • 1970-01-01
    • 2011-06-27
    • 1970-01-01
    相关资源
    最近更新 更多