{"value":"为了给企业提供更加易用的应用层软件,越来越多的软件提供商推出了 SaaS 产品。亚马逊云科技 Marketplace(以下简称 Marketplace)是一个提供甄选的数字化产品的平台,能够帮助 SaaS 厂商降低销售成本,触达更多的客户,是很多 SaaS 厂商的首选。\n\n通过软件即服务(SaaS)产品,您部署了在亚马逊云科技提供的基础设施上的软件,并允许买家可以直接通过 Marketplace 来使用您的软件。您需要在您的软件中管理客户访问、账户创建、资源配置和账户管理。\n\n在 Marketplace 中上架您基于 SaaS 模式的软件过程中,您需要与 Marketplace SaaS 提供的多个 API 进行对接,具体对接的方式您可以参考卖家指南。\n\n在您的 SaaS 中,建议您将与 Marketplace SaaS API 进行接口集成的部分作为独立模块进行研发和管理,并运行在您的亚马逊云科技账号中。\n\n在上一个文章《在亚马逊云科技 Marketplace 上的 SaaS 架构设计(一)——跨多账户对接篇》中,我们基于 SaaS 架构设计的角度介绍了多个亚马逊云科技账户中构建 Marketplace SaaS 的 API 对接的最佳实践,除了多亚马逊云科技的账户情况可能会发生,还会发生另外一种情况,就是卖家将同一个 SaaS 应用程序,根据功能以及业务上的要求,拆分成了多个 SaaS 产品上架到了 Marketplace 中,这意味着同一个卖家账户,在亚马逊云科技 Marketplace 上架了多款 SaaS 产品,但是这些 SaaS 产品的租户与账户系统是相同同时客户登陆的是相同的 SaaS 应用程序。\n\n在这种情况下,与 Marketplace 的租户 API 对接过程将会变得复杂,本文将基于这个场景,进行 SaaS 架构设计的介绍。\n\n\n### **租户对接介绍**\n\n在您的 SaaS 应用程序与 Marketplace API 进行对接的过程中,其中一个重要的就是租户的对接,这里涉及到的 API 为 ResolveCustomer。\n\nResolveCustomer 是由 SaaS 应用程序在注册过程中调用的。当买家在注册过程中访问您提交给我们的落地页面时,买家会通过他们的浏览器提交一个注册令牌。注册令牌通过该API被解析,以获得CustomerIdentifier 和产品代码。\n\n- 接收新用户 API:**ResolveCustomer**\n\n当一个用户从 Marketplace 订阅并跳转到您的 SaaS 应用程序后,您将会面临您的应用程序与亚马逊云科技进行用户对接的过程,该用户在第一次到达您的 SaaS 应用程序时,他具备 Amazon Web Service 的账户身份,同时该用户在您的 SaaS 应用程序中载入后,他也具备您的 SaaS 租户属性,为了日后您与 Marketplace 进行交互,您需要在这一步骤中进行 API 集成,完成该用户2个身份的绑定。\n\nResolveCustomer API 是整个 SaaS API 集成的第一步,也是客户通过 Marketplace 进入到您的 SaaS 应用的第一步,在这一步骤中,我们需要通过该 API 完成两部分工作:\n\n- 验证新客户\n\n在客户订阅您的产品后,他们将被重定向到执行的 URL。该重定向是一个 POST 请求,包括一个临时令牌。然后,您的应用程序需要通过调用 Marketplace 计量服务 API 中的 ResolveCustomer,将令牌换成客户 ID。在获得客户 ID 后,将其保存在您的应用程序中,以便将来调用。\n\n- 载入您的新客户\n\n在成功地验证了一个客户后,让他们加入您的应用程序。例如,让他们填写一个表格来创建一个新的用户账户。或者,为他们提供进入应用程序的后续步骤。您的应用程序可以根据客户的信息来自动化的装载该客户所需要的后续资源与服务。\n\n![image.png](https://dev-media.amazoncloud.cn/5814661af19d400abcd499a3125b242a_image.png)\n\n如上图所示,在使用 ResolveCustomer API 的过程中,首先需要从 Http Request 中获取 token,当客户从 Marketplace 跳转到您的应用程序过程中, Marketplace 会给您上线过程中提交的 URL 发送 POST 请求,您需要从该请求中通过获取 x-amzn-marketplace-token 获取该用户的身份 token,然后调用 ResolveCustomer API 获得 CustomerIdetifier 和 ProductCode,其中 CustomerIdetifier 为该客户在 Amazon Web Services 上身份的标示,ProductCode 是产品的唯一标识码。\n\n您需要将 CustomerIdetifier 与 ProductCode 基于您应用程序逻辑进行业务处理,并用于后续该用户与 Amazon Web Services Marketplace API 交互。\n\n\n### **案例背景**\n\n以上为正常情况下的租户对接过程,但如果在 Marketplace 中您使用了相同的卖家账号上架了多款 SaaS 产品,但这些 SaaS 应用程序使用了相同的租户注册与验证系统同时客户登陆的是同一套 SaaS 应用程序,将会面临更加复杂的问题。\n\n对于亚马逊云科技 Marketplace 中基于 SaaS 交付的产品中,有多种价格模型可以选择,本篇文章所涉及的内容重点为租户系统对接的设计,订阅模型与合约模型作为仅作为租户系统对接设计的后续行为,所以在下文中,将以基于订阅的价格模型作为举例。\n\n在本文章的举例中,有两个您上架的 SaaS 产品,分别为\n\n#### **SaaS1**\n\n产品 ID 为 product1111\n\n#### **SaaS2**\n\n产品 ID 为 product2222\n\n\n### **SaaS架构设计**\n\n在正常的情况下,当客户通过 Marketplace 购买您的产品后,我们会建议您将 SaaS 应用程序的租户与通过 Marketplace API 换到的 CustomerIdetifier 进行绑定,而产品ID则根据您的需求进行合理的持久化,这样您的 SaaS 应用程序中的用户在产生消费行为过程中,您会将该行为记录并整合到您的用户的租户中,并通过 Marketplace API 与 Marketplace 进行计价的交互,在这种背景下,租户对接设计一般为:\n\n![微信截图_20221025154330.png](https://dev-media.amazoncloud.cn/423dd7a560eb447d9033cb6ba3613a2c_%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_20221025154330.png)\n\n在上面所举例的租户设计中,Marketplace_Id字段代表着持久化的Marketplace CustomerIdetifier,该字段存在值代表着该租户是通过Marketplace平台进入到SaaS应用程序中,未来该租户的所有计费相关的行为将使用该字段的值,该SaaS应用程序的产品ID以及计费维度和使用量来与Marketplace进行交互,如下所示:\n\n```\n{\n \"ProductCode\": \" product1111\",\n \"UsageRecords\": [ \n { \n \"CustomerIdentifier\": \"5ha1maxi\",\n \"Dimension\": \"Data\",\n \"Quantity\": 2,\n \"Timestamp\": xxxxx\n }\n ]\n}\n```\n\n但当中您使用了相同的卖家账号上架了多款 SaaS 产品,但这些 SaaS 应用程序使用了相同的租户注册与验证系统,这种架构设计会导致以下问题:\n\n**无法控制 SaaS 应用程序的权限**\n\n用户通过 Marketplace 选择您其中一款 SaaS 产品购买并注册/登陆后,因为您之前的 SaaS 架构设计原因,您将无法区别该用户来源于哪个 Marketplace 中您上架的产品,所以您无法进行 SaaS 应用程序的权限控制\n\n**部分情况下无法进行 API 交互**\n\n用户通过 Marketplace 选择您其中一款 SaaS 产品购买并注册/登陆后,可能会在您的 SaaS 应用程序中使用了您另外一款上架的 SaaS 应用程序的功能,您的 SaaS 应用程序会根据该功能去调用 Marketplace 计费 API 与 Marketplace 交互,但是由于该用户并没有通过 Marketplace 订阅您的另一款产品,您会得到一个错误的返回。\n\n所以在这种特殊的情况下,您的 SaaS 架构设计在租户层根据您上架的产品数量来进行标示的区分并与您的租户系统进行绑定,如下图所示:\n\n![微信截图_20221025154330.png](https://dev-media.amazoncloud.cn/a24d598a64904bf19ffc44dc621fc8b0_%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_20221025154330.png)\n\n或者\n\n```\n{\n \"Tenant_T\": [\n {\n \"TenantID\": \"AAA\",\n \"User\": [\n {\n \"UserID\": \"111\"\n },\n {\n \"UserID\": \"222\"\n },\n {\n \"UserID\": \"333\"\n }\n ],\n \"Marketplace\": [\n {\n\t\t\t \"ProductID\": \"product111\",\n \"MarketplaceID\": \"5ha1maxi\"\n }\n ]\n },\n {\n \"TenantID\": \"BBB\",\n \"User\": [\n {\n \"UserID\": \"111\"\n },\n {\n \"UserID\": \"222\"\n }\n ],\n \"Marketplace\": [\n {\n\t\t\t \"ProductID\": \"product111\",\n \"MarketplaceID\": \"5ha1maxi\"\n },\n {\n\t\t\t \"ProductID\": \"product222\",\n \"MarketplaceID\": \" d92nwk21\"\n }\n ]\n }\n ]\n}\n```\n\n在这种租户架构下,您可以清晰的区分出 Marketplace 端的租户,您上架的产品以及您的 SaaS 应用程序的租户之间的关系,当某一个用户进行您的 SaaS 应用程序功能的选择时,你需要找到该用户对应的租户以及该租户中通过 Marketplace 订阅的产品,如果该功能所属的产品已经被订阅,您可以直接使用这些信息于 Marketplace API 交互进行用量的传输,如果该用户并没有订阅该产品,您的应用程序应该进行相应的处理,比如禁止该用户使用此功能并引导客户至相应的 Marketplace 上您的产品进行订阅后再进行使用。\n\n \n\n### **总结**\n\n该文章中说明了在 SaaS 架构设计中,在根据业务和产品的需求,需要将 SaaS 应用程序拆分多个产品进行上架的情况下,如何进行 SaaS 租户的设计以及权限的判断,我们建议您在非必要情况下,不要进行单一 SaaS 应用程序的的拆分而上架多个 Marketplace 产品,但如果您的需求必须如此,请您进行好响应的 SaaS 架构设计避免用户体验的降低或者造成您的损失。\n\n### **本篇作者**\n\n![image.png](https://dev-media.amazoncloud.cn/ad7e78677be04b408249c3b44de6a443_image.png)\n\n#### **张明月**\n\n合作伙伴解决方案架构师","render":"<p>为了给企业提供更加易用的应用层软件,越来越多的软件提供商推出了 SaaS 产品。亚马逊云科技 Marketplace(以下简称 Marketplace)是一个提供甄选的数字化产品的平台,能够帮助 SaaS 厂商降低销售成本,触达更多的客户,是很多 SaaS 厂商的首选。</p>\n<p>通过软件即服务(SaaS)产品,您部署了在亚马逊云科技提供的基础设施上的软件,并允许买家可以直接通过 Marketplace 来使用您的软件。您需要在您的软件中管理客户访问、账户创建、资源配置和账户管理。</p>\n<p>在 Marketplace 中上架您基于 SaaS 模式的软件过程中,您需要与 Marketplace SaaS 提供的多个 API 进行对接,具体对接的方式您可以参考卖家指南。</p>\n<p>在您的 SaaS 中,建议您将与 Marketplace SaaS API 进行接口集成的部分作为独立模块进行研发和管理,并运行在您的亚马逊云科技账号中。</p>\n<p>在上一个文章《在亚马逊云科技 Marketplace 上的 SaaS 架构设计(一)——跨多账户对接篇》中,我们基于 SaaS 架构设计的角度介绍了多个亚马逊云科技账户中构建 Marketplace SaaS 的 API 对接的最佳实践,除了多亚马逊云科技的账户情况可能会发生,还会发生另外一种情况,就是卖家将同一个 SaaS 应用程序,根据功能以及业务上的要求,拆分成了多个 SaaS 产品上架到了 Marketplace 中,这意味着同一个卖家账户,在亚马逊云科技 Marketplace 上架了多款 SaaS 产品,但是这些 SaaS 产品的租户与账户系统是相同同时客户登陆的是相同的 SaaS 应用程序。</p>\n<p>在这种情况下,与 Marketplace 的租户 API 对接过程将会变得复杂,本文将基于这个场景,进行 SaaS 架构设计的介绍。</p>\n<h3><a id=\"_13\"></a><strong>租户对接介绍</strong></h3>\n<p>在您的 SaaS 应用程序与 Marketplace API 进行对接的过程中,其中一个重要的就是租户的对接,这里涉及到的 API 为 ResolveCustomer。</p>\n<p>ResolveCustomer 是由 SaaS 应用程序在注册过程中调用的。当买家在注册过程中访问您提交给我们的落地页面时,买家会通过他们的浏览器提交一个注册令牌。注册令牌通过该API被解析,以获得CustomerIdentifier 和产品代码。</p>\n<ul>\n<li>接收新用户 API:<strong>ResolveCustomer</strong></li>\n</ul>\n<p>当一个用户从 Marketplace 订阅并跳转到您的 SaaS 应用程序后,您将会面临您的应用程序与亚马逊云科技进行用户对接的过程,该用户在第一次到达您的 SaaS 应用程序时,他具备 Amazon Web Service 的账户身份,同时该用户在您的 SaaS 应用程序中载入后,他也具备您的 SaaS 租户属性,为了日后您与 Marketplace 进行交互,您需要在这一步骤中进行 API 集成,完成该用户2个身份的绑定。</p>\n<p>ResolveCustomer API 是整个 SaaS API 集成的第一步,也是客户通过 Marketplace 进入到您的 SaaS 应用的第一步,在这一步骤中,我们需要通过该 API 完成两部分工作:</p>\n<ul>\n<li>验证新客户</li>\n</ul>\n<p>在客户订阅您的产品后,他们将被重定向到执行的 URL。该重定向是一个 POST 请求,包括一个临时令牌。然后,您的应用程序需要通过调用 Marketplace 计量服务 API 中的 ResolveCustomer,将令牌换成客户 ID。在获得客户 ID 后,将其保存在您的应用程序中,以便将来调用。</p>\n<ul>\n<li>载入您的新客户</li>\n</ul>\n<p>在成功地验证了一个客户后,让他们加入您的应用程序。例如,让他们填写一个表格来创建一个新的用户账户。或者,为他们提供进入应用程序的后续步骤。您的应用程序可以根据客户的信息来自动化的装载该客户所需要的后续资源与服务。</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/5814661af19d400abcd499a3125b242a_image.png\" alt=\"image.png\" /></p>\n<p>如上图所示,在使用 ResolveCustomer API 的过程中,首先需要从 Http Request 中获取 token,当客户从 Marketplace 跳转到您的应用程序过程中, Marketplace 会给您上线过程中提交的 URL 发送 POST 请求,您需要从该请求中通过获取 x-amzn-marketplace-token 获取该用户的身份 token,然后调用 ResolveCustomer API 获得 CustomerIdetifier 和 ProductCode,其中 CustomerIdetifier 为该客户在 Amazon Web Services 上身份的标示,ProductCode 是产品的唯一标识码。</p>\n<p>您需要将 CustomerIdetifier 与 ProductCode 基于您应用程序逻辑进行业务处理,并用于后续该用户与 Amazon Web Services Marketplace API 交互。</p>\n<h3><a id=\"_40\"></a><strong>案例背景</strong></h3>\n<p>以上为正常情况下的租户对接过程,但如果在 Marketplace 中您使用了相同的卖家账号上架了多款 SaaS 产品,但这些 SaaS 应用程序使用了相同的租户注册与验证系统同时客户登陆的是同一套 SaaS 应用程序,将会面临更加复杂的问题。</p>\n<p>对于亚马逊云科技 Marketplace 中基于 SaaS 交付的产品中,有多种价格模型可以选择,本篇文章所涉及的内容重点为租户系统对接的设计,订阅模型与合约模型作为仅作为租户系统对接设计的后续行为,所以在下文中,将以基于订阅的价格模型作为举例。</p>\n<p>在本文章的举例中,有两个您上架的 SaaS 产品,分别为</p>\n<h4><a id=\"SaaS1_48\"></a><strong>SaaS1</strong></h4>\n<p>产品 ID 为 product1111</p>\n<h4><a id=\"SaaS2_52\"></a><strong>SaaS2</strong></h4>\n<p>产品 ID 为 product2222</p>\n<h3><a id=\"SaaS_57\"></a><strong>SaaS架构设计</strong></h3>\n<p>在正常的情况下,当客户通过 Marketplace 购买您的产品后,我们会建议您将 SaaS 应用程序的租户与通过 Marketplace API 换到的 CustomerIdetifier 进行绑定,而产品ID则根据您的需求进行合理的持久化,这样您的 SaaS 应用程序中的用户在产生消费行为过程中,您会将该行为记录并整合到您的用户的租户中,并通过 Marketplace API 与 Marketplace 进行计价的交互,在这种背景下,租户对接设计一般为:</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/423dd7a560eb447d9033cb6ba3613a2c_%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_20221025154330.png\" alt=\"微信截图_20221025154330.png\" /></p>\n<p>在上面所举例的租户设计中,Marketplace_Id字段代表着持久化的Marketplace CustomerIdetifier,该字段存在值代表着该租户是通过Marketplace平台进入到SaaS应用程序中,未来该租户的所有计费相关的行为将使用该字段的值,该SaaS应用程序的产品ID以及计费维度和使用量来与Marketplace进行交互,如下所示:</p>\n<pre><code class=\"lang-\">{\n "ProductCode": " product1111",\n "UsageRecords": [ \n { \n "CustomerIdentifier": "5ha1maxi",\n "Dimension": "Data",\n "Quantity": 2,\n "Timestamp": xxxxx\n }\n ]\n}\n</code></pre>\n<p>但当中您使用了相同的卖家账号上架了多款 SaaS 产品,但这些 SaaS 应用程序使用了相同的租户注册与验证系统,这种架构设计会导致以下问题:</p>\n<p><strong>无法控制 SaaS 应用程序的权限</strong></p>\n<p>用户通过 Marketplace 选择您其中一款 SaaS 产品购买并注册/登陆后,因为您之前的 SaaS 架构设计原因,您将无法区别该用户来源于哪个 Marketplace 中您上架的产品,所以您无法进行 SaaS 应用程序的权限控制</p>\n<p><strong>部分情况下无法进行 API 交互</strong></p>\n<p>用户通过 Marketplace 选择您其中一款 SaaS 产品购买并注册/登陆后,可能会在您的 SaaS 应用程序中使用了您另外一款上架的 SaaS 应用程序的功能,您的 SaaS 应用程序会根据该功能去调用 Marketplace 计费 API 与 Marketplace 交互,但是由于该用户并没有通过 Marketplace 订阅您的另一款产品,您会得到一个错误的返回。</p>\n<p>所以在这种特殊的情况下,您的 SaaS 架构设计在租户层根据您上架的产品数量来进行标示的区分并与您的租户系统进行绑定,如下图所示:</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/a24d598a64904bf19ffc44dc621fc8b0_%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_20221025154330.png\" alt=\"微信截图_20221025154330.png\" /></p>\n<p>或者</p>\n<pre><code class=\"lang-\">{\n "Tenant_T": [\n {\n "TenantID": "AAA",\n "User": [\n {\n "UserID": "111"\n },\n {\n "UserID": "222"\n },\n {\n "UserID": "333"\n }\n ],\n "Marketplace": [\n {\n\t\t\t "ProductID": "product111",\n "MarketplaceID": "5ha1maxi"\n }\n ]\n },\n {\n "TenantID": "BBB",\n "User": [\n {\n "UserID": "111"\n },\n {\n "UserID": "222"\n }\n ],\n "Marketplace": [\n {\n\t\t\t "ProductID": "product111",\n "MarketplaceID": "5ha1maxi"\n },\n {\n\t\t\t "ProductID": "product222",\n "MarketplaceID": " d92nwk21"\n }\n ]\n }\n ]\n}\n</code></pre>\n<p>在这种租户架构下,您可以清晰的区分出 Marketplace 端的租户,您上架的产品以及您的 SaaS 应用程序的租户之间的关系,当某一个用户进行您的 SaaS 应用程序功能的选择时,你需要找到该用户对应的租户以及该租户中通过 Marketplace 订阅的产品,如果该功能所属的产品已经被订阅,您可以直接使用这些信息于 Marketplace API 交互进行用量的传输,如果该用户并没有订阅该产品,您的应用程序应该进行相应的处理,比如禁止该用户使用此功能并引导客户至相应的 Marketplace 上您的产品进行订阅后再进行使用。</p>\n<h3><a id=\"_147\"></a><strong>总结</strong></h3>\n<p>该文章中说明了在 SaaS 架构设计中,在根据业务和产品的需求,需要将 SaaS 应用程序拆分多个产品进行上架的情况下,如何进行 SaaS 租户的设计以及权限的判断,我们建议您在非必要情况下,不要进行单一 SaaS 应用程序的的拆分而上架多个 Marketplace 产品,但如果您的需求必须如此,请您进行好响应的 SaaS 架构设计避免用户体验的降低或者造成您的损失。</p>\n<h3><a id=\"_151\"></a><strong>本篇作者</strong></h3>\n<p><img src=\"https://dev-media.amazoncloud.cn/ad7e78677be04b408249c3b44de6a443_image.png\" alt=\"image.png\" /></p>\n<h4><a id=\"_155\"></a><strong>张明月</strong></h4>\n<p>合作伙伴解决方案架构师</p>\n"}