Rails 7集成omniauth-shopify-oauth2遇invalid_site错误及权限疑问
问题与解决方案:Shopify OAuth认证错误及订单权限疑问
一、"invalid_site encountered" 错误解决办法
针对你在Rails 7中使用omniauth-shopify-oauth2 gem时遇到的这个错误,可从以下几个方向排查解决:
- 校验店铺域名格式:确保用户输入的店铺域名是完整的Shopify官方格式,比如
your-store.myshopify.com,不能只输入店铺名称,也不能带http://或https://前缀。该gem会严格校验域名有效性,格式不符直接触发错误。 - 核对回调地址配置:登录Shopify合作伙伴后台,检查应用的回调地址(包括localhost和Ngrok地址)与Rails项目中的实际回调路由完全一致。比如你的回调路由是
/users/auth/shopify/callback,后台要填写完整URL,例如https://xxx.ngrok.io/users/auth/shopify/callback,注意不要加多余斜杠或拼写错误。 - 完善Devise Omniauth配置:如果是动态获取店铺域名的场景,需要在
config/initializers/devise.rb的配置中加入setup: true,确保授权请求能正确接收shop参数。同时,跳转至授权页面时必须携带shop参数,比如跳转地址应为/users/auth/shopify?shop=your-store.myshopify.com。 - 更新gem版本:老版本的
omniauth-shopify-oauth2可能存在域名校验逻辑的bug,尝试更新到最新稳定版。修改Gemfile:
然后执行gem 'omniauth-shopify-oauth2', '~> 2.0'bundle update omniauth-shopify-oauth2。
二、店铺安装应用后能否获取订单信息?
是的,但需要满足两个核心条件:
- 权限已申请并被同意:你的代码中已经在OAuth scope里声明了
read_orders权限,店铺主在安装应用时会看到该权限申请提示,只有当他们同意授权后,应用才能获得访问订单数据的权限。 - 正确调用Shopify Admin API:拿到OAuth返回的
oauth_token后,需要用该令牌调用Shopify的Admin API获取订单。比如使用shopify_apigem的示例代码:
shopify_client = ShopifyAPI::Clients::Rest::Admin.new( shop: auth.uid, # auth.uid即为店铺完整域名 access_token: auth.credentials.token ) response = shopify_client.get(path: "/admin/api/2024-07/orders.json") orders = response.body["orders"]
注意要使用Shopify当前支持的API版本,避免因版本过期导致的权限或接口访问问题。
你提供的相关代码
config/initializers/devise.rb
config.omniauth :shopify, 'app_id', 'app_secret', scope: 'read_orders'
omniauthcallback_controller.rb
def shopify @user = User.from_omniauth(request.env['omniauth.auth']) if @user.persisted? sign_in_and_redirect @user, event: :authentication set_flash_message(:notice, :success, kind: 'Shopify') if is_navigational_format? else session['devise.shopify_data'] = request.env['omniauth.auth'] redirect_to new_user_registration_url end end
app/models/user.rb
def from_omniauth(auth, signed_in_resource=nil) auth_provider = auth.provider auth_uid = auth.uid Rails.logger.warn ">>>>>>>17>>>>>>#{auth.inspect}" p = AuthProvider.where(provider: auth_provider, user_id: id).first_or_initialize p.provider = auth_provider p.uid = auth_uid p.oauth_token = auth.credentials.token p.oauth_expires_at = Time.at(auth.credentials.expires_at) p.refresh_token = auth.credentials.refresh_token end
内容的提问来源于stack exchange,提问作者Md Shafayet Jamil
相关产品推荐
相关产品推荐

