在Shopify中无法在应用程序中嵌入站点(X-Frame-Options)

4

我最近几周一直在开发我的第一个RoR/Shopify应用程序,现在它快要完成了。唯一让我困扰的是应用收费问题。当用户在商店中看到我的应用程序时,他会点击“获取”,然后认证过程就开始了。应用程序正在安装,用户可以接受/拒绝收费。如果他拒绝了,他将被重定向到商店中我的应用列表。 现在我的问题是:如果用户拒绝支付费用,我的应用程序仍然被安装。如果他第二次点击我的横幅广告,我需要检查他是否正在为此付款。我通过以下方式进行检查:

if (ShopifyAPI::RecurringApplicationCharge.current)
   some logic since the charge is valid
else 
   redirect_to billing_index_path(:shop_url => cur_shop_url)

我的想法是,如果用户还没有付款,则再次显示收费弹出窗口。但这并不起作用,并且我收到一个错误提示,称因为X-Frame-Options被设置为DENY,我的网站无法显示。我已经尝试在application_controller.rb和application.rb中删除选项,使用以下任一选项:

Response.headers.delete('X-Frame-Options') 

并且

config.action_dispatch.default_headers.delete('X-Frame-Options') 

分别地,第一次用户安装应用程序时,一切似乎都正常,嵌入、逻辑等。但是,在用户尝试第二次使用后,一切都变得混乱不堪。如何在每次用户访问我的应用程序时嵌入所有站点?我看到Shopify的响应默认带有DENY头,但我相信一定有解决这个问题的方法。我不能让用户每次都卸载应用程序,谢谢。

我也想知道这个问题的答案。据我所知,这是Shopify模式中未解决的一个漏洞。我使用Sinatra,在尝试显示第二/第三或更多次付款确认对话框时遇到了相同的问题。 - David Lazar
为什么不添加一个非常有限的免费计划呢?这样,您就可以吸引更多的商家加入,让他们尝试您的应用程序的魔力。 - alexandresaiz
@alexandresaiz,我现在按照我下面描述的方式完成了。我添加了7天的试用期,应该足够了。我可以免费为第一个应用程序提供服务,但这不是我决定的事情 ;) - voskart
Shopify API:最糟糕的开发体验 - Rebs
3个回答

7
Shopify不会处理他们的付款批准表格中的302重定向。原因是,您的应用程序嵌入在iframe中。无论来源如何,付款确认终端点都拒绝嵌入式iframe - 他们甚至不会将自己的网站列入白名单!!这意味着您不能简单地进行表单提交并在订阅确认URL成功时进行302跳转,那太简单了。您必须编写一些javascript代码来获取确认URL并执行window.top.location = confirm_url;。您必须退出iframe,否则Shopify也将拒绝您的重定向功能,并且您将回到之前的状态。或者,您可以在新窗口中打开链接。我不得不将我的“快速简单”应用程序转换为发出Ajax调用以提交订阅信息到我的服务器,然后使用返回的确认URL进行JS重定向。不得不说,Shopify的API文档实在太少了,而且实现非常糟糕。在每个关键时刻,他们的“API”都会设置障碍。

1
问题在于Shopify不允许嵌入式应用程序进行302重定向。我遇到了应用程序超时的问题。原来这个错误出现在JavaScript控制台中。X-Frame-Options拒绝加载:https://<shop_name>.myshopify.com/admin/charges/<id>/confirm_recurring_application_charge?signature=<signature_hash>不允许框架。我按照@Rebs的指示将302重写为JavaScript重定向(window.top.location),然后它就正常工作了。 - stanhope
1
我制作了一个屏幕录像,展示了这个问题,并在2015年11月27日提交了2421717号工单向Shopify报告了这个问题,但截至2016年1月18日,他们选择不采取任何行动。 - stanhope
@Rebs 我也遇到了同样的问题,我通过使用ajax调用来获取订阅信息解决了这个问题。然后使用你建议的方法重定向到确认页面。但现在我无法返回到Shopify的iframe范围内。 - Riken Mehta

1
请将以下代码添加到config/application.rb文件中。
config.action_dispatch.default_headers['P3P'] = 'CP="Not used"'
config.action_dispatch.default_headers.delete('X-Frame-Options')
config.active_record.raise_in_transactional_callbacks = true

欢迎来到Stack Overflow!虽然这段代码片段可能解决了问题,但是包括解释真的很有帮助,以提高您的帖子质量。请记住,您正在回答未来读者的问题,而不仅仅是现在提问的人!请[编辑]您的答案以添加解释,并指出适用的限制和假设。 - Toby Speight

0

好吧,这绝不是我要寻找的解决方案,但没办法。如果我发现收费无效,我会将用户重定向到我的billing_error_path。在那里,我有一个带有link_to按钮的shopify-app列表。在那里,他可以再次点击“获取”,然后被重新定向回我的商店,可以再次接受/拒绝费用。可能不是最好的解决方案,但至少它做到了我所期望的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接