假设你想让用户在一定时间内试用你的应用程序的服务,比如30天。你怎么能让用户注册,然后在试用期过后阻止他们呢?你可以轻松地利用Auth0 Actions来实现这一结果。
设置示例应用程序
为了向你展示如何为你的应用程序启用试用期,本文将提到一个允许用户访问一个虚构的在线目录的样本Web应用程序。
你在本文中要使用的示例应用程序是用C#构建的,需要在你的机器上安装.NET。然而,你要实现的用户注册定制与你的应用程序的具体编程语言和框架无关。
你可以通过以下命令克隆GitHub仓库来下载该样本程序。
git clone https://github.com/auth0-blog/acme-aspnet-mvc.git
一旦你下载了它,看看README文件,并按照其指示配置应用程序以使用Auth0。你需要一个Auth0账户,如果你还没有,你可以注册一个免费账户。
如果你想了解样本应用程序实现的细节,这篇博文描述了它是如何与Auth0认证服务整合的。
在配置好样本应用程序后,你可以用以下命令运行它。
dotnet run
现在,将你的浏览器指向https://localhost:7095/地址,你应该得到以下页面。
Auth0行动和流程
一旦你确保了你的应用程序被正确地配置和运行,让我们简单地探讨一下Auth0的功能,这将使你能够实施试用期。Auth0动作和流程。
Auth0 Actions是运行在Node.js环境中的JavaScript函数,当一些内部Auth0 Flows中的特定事件发生时执行。
Auth0流程是可以用Actions扩展的过程。每个流程由一个或多个触发器组成,并代表了逻辑管道,信息在Auth0旅程中的一个点上移动。
例如,你可以考虑登录流程,它在用户登录时运行。这个流程有一个登录后的触发器:用户登录后触发的事件。你可以通过一个或多个Action来处理这个事件。换句话说,你可以把Actions看作是事件处理程序,当Auth0流程中的一个特定事件发生时运行。
下面是一个Action*(AddRoles*)的图形表示,它将在用户登录后在登录流程中执行。
以下是可用的Auth0流程,你可以用Action进行定制。
- 登录,在用户登录时运行。
- 用户注册前,在一个用户被添加到用户商店之前运行。
- 用户注册后,在用户被添加到用户商店后运行。
- 修改密码后,在用户修改密码后运行。
- 发送电话信息,当你配置一个自定义的多因素认证(MFA)提供者时运行。
- 机器对机器,在使用客户凭证流程向客户发放访问令牌时运行。
你将使用这些流程中的几个来实现样本应用程序的试用期功能。
要了解更多关于Actions的信息,你可以查看这些博客文章,了解Auth0 Actions的快速介绍,以及它们与已废弃的Rules和Hooks的比较。
试用期的实施
一旦你对Auth0流程和Actions有了一个概念,让我们概述一下如何实现样本应用程序的试用期功能。你可以确定以下步骤。
- 开始试用:当用户向应用程序注册以访问其目录时,你将计算试用期的到期日并将其存储在服务器端。你将通过创建一个自定义用户注册前流程的动作来完成这一步骤。你还会了解到你可以利用Auth0来适时地存储试用期的到期日。
- 检查试用期的有效性:每当用户登录到样本应用程序时,你必须比较当前日期和到期日期,以确定试用期是否仍然有效。如果试用期仍然有效,用户就被允许访问目录。你将通过定制带有动作的登录流程来实现这一步骤。
- 处理试用期过期的问题:当试用期过期时,用户不允许访问目录。他们将被重定向到一个页面,邀请他们购买对应用程序服务的完整访问。这个步骤的实现依赖于试用有效期检查Action和对样本应用程序的一些修改。
接下来的章节将详细介绍如何实现每个步骤。
开始试用
让我们从实现试用的第一步开始:当用户在你的应用程序上注册时,注册到期日期。
访问你的Auth0仪表板,在左侧菜单的Actions项目下选择Flows。你应该在你的浏览器中看到以下屏幕。
这个屏幕显示了你可以用你的行动定制的Auth0流程。为了我们的目的,点击 "*用户注册前 "*瓦片,你将进入以下页面。
这个页面允许你在用户注册前流程中添加一个或多个操作。你可以添加两种类型的操作。
- 安装的动作,即由第三方建立并在Auth0市场上发布的可使用的动作。
- 自定义动作,即你从头开始创建的动作。
在这种情况下,你将创建你自己的自定义动作。因此,点击添加动作部分右上角的 "+"图标,并选择建立自定义菜单项,如下图所示。
你会被要求输入一个动作的名称。提供 "开始试用期"名称,其他字段保持不变,如下图所示。
现在,点击创建按钮,你将进入动作编辑器。你的屏幕应该如下图所示。
你在动作编辑器中找到的代码是JavaScript函数,它将在用户注册样本应用程序后执行。这个函数将在运行于Auth0端的Node.js环境中被导出。
该JavaScript函数有一个event
参数和一个api
参数。
event
参数提供了一些关于当前运行环境的信息。例如,它允许你访问当前用户的数据、当前请求、租户等。关于用户注册前event
对象的更多细节,请查看文档。
api
参数提供了改变流量行为的方法。例如,它允许你拒绝访问你的应用程序或为用户或应用程序设置特定的元数据。关于用户注册前api
对象的更多细节,请查看文档。
为了启动即将注册的用户的试用期,你必须在这个JavaScript函数的主体中写一些代码。所以,用下面的代码替换Action编辑器的内容。
exports.onExecutePreUserRegistration = async (event, api) => {
const today = new Date();
const expirationDate = new Date();
expirationDate.setDate(today.getDate() + 30);
api.user.setAppMetadata("trial_expiration_date", expirationDate);
};
这段代码通过在当前日期上增加30天来计算到期日期,并将其分配给绑定在当前用户上的app_metadata
对象的trial_expiration_date
属性。实际上,这个 setAppMetadata()
方法为app_metadata
对象创建一个新的自定义属性,如果它不存在的话。要了解更多关于管理元数据的信息,请查看文档。
现在你有了在注册时为用户设置试用期到期日的动作。点击 "保存草稿"按钮保存你的修改,然后点击 "部署"按钮,使该动作在用户注册前流程中可用。然后,通过点击左上角的*<-返回流程*>链接回到流程编辑器。
在流程编辑器中,点击添加动作部分的自定义标签。现在你应该看到你刚刚创建的动作,如下图所示。
从 "添加动作"部分拖动 "开始试用期动作",将其放在流程图的 "开始"和 "完成"节点之间。你应该得到以下结果。
点击 "应用"按钮,确认你的改变。你的应用程序现在已经准备好在用户注册时创建一个试用期的失效日期。
检查试用期的有效性
下一步的重点是检查用户登录时试用期是否过期。
移动到Auth0仪表板中的流程列表,选择登录流程。正如你在上一节学到的,你必须通过点击流程编辑器中添加动作部分的建立自定义菜单项来创建一个自定义动作。
给你的新动作命名为 "检查试用有效期",然后点击 "创建"按钮,进入动作编辑器。这时你会在编辑器中发现以下代码。
exports.onExecutePostLogin = async (event, api) => {
};
这是一个JavaScript函数,将在用户登录后执行。和以前一样,这个函数有两个参数,event
和api
,与当前运行环境的信息和改变当前Flow行为的方法有关。尽管这些参数的名字和以前一样,但它们的结构是不同的,因为它们与当前的Flow严格相关。具体细节请参考post-loginevent
对象和post-loginapi
对象文档和post-loginapi
对象文档。
要检查当前用户的试用期是否有效,请将Action编辑器中的代码替换为以下内容。
exports.onExecutePostLogin = async (event, api) => {
const today = new Date();
const expirationDate = new Date(event.user.app_metadata["trial_expiration_date"]);
if (today > expirationDate) {
api.access.deny("trial_expiration");
}
};
这段代码从app_metadata
对象中检索当前用户的到期日期,并与当前日期进行比较。如果当前日期在过期日期之前,Action不做任何事情。否则,将通过 api.access.deny()
方法拒绝访问。传递给该方法的字符串trial_expiration
,简要解释了拒绝访问的原因。 deny()
方法传递的字符串简要地解释了拒绝访问的原因。
现在你的第二个Action已经准备好了,你知道该怎么做:保存它,然后部署它,最后回到流程,把它放到那里。如果你到目前为止做了所有的事情,你的登录流程应该是这样的。
测试试用期
现在你已经准备好测试你到目前为止所建立的东西了。
注册一个新用户
如果还没有运行,通过在终端窗口输入dotnet run
命令来启动示例应用程序。
动作是在Auth0侧实现和部署的,当任何一个Auth0流程参与时,它们就会运行。因此,如果你的应用程序已经在运行,这并不重要。你不需要重新启动它。
然后,点击应用程序主页右上角的 "登录"链接。在Auth0通用登录页面,点击下面强调的注册链接。
你将被要求提供一个电子邮件和密码,为你的应用程序创建一个新的用户。一旦新用户创建完毕,你就可以浏览应用程序的目录。
检查试用期的到期日
让我们看看在Auth0方面发生了什么。进入你的Auth0仪表板的用户管理部分,选择新创建的用户。向下滚动包含用户数据的页面,你应该发现app_metadata字段有一个类似于下面的JSON对象。
正如你所看到的,这个字段显示了app_metadata
对象,其中有trial_expiration_date
在注册时设置的开始试用期动作。
使试用期过期
为了验证Check Trial Validity Action是否按预期工作,我们不能等待...一个月。你可以通过简单地编辑app_metadata字段来加速试用期的过期。因此,改变trial_expiration_date
的值,使其在当前日期之前,然后点击保存按钮,更新用户资料。
测试试用期的到期情况
如果你已经登录到应用程序,点击页面右上角的注销链接,再次登录到应用程序。
这一次,你不应该能够登录并访问应用程序的目录。你将看到的是一个像下面这样的页面。
你可以推断出,你不能登录应用程序是因为你的试用期已过,但用户体验实际上不是你所期望的那样好。
改善用户体验
到目前为止,我们实现的处理试用期过期的方法有点粗糙。实际上,除非你的应用程序能捕捉到不能访问的原因并给出用户友好的反馈,否则用户不会有好的体验。
正确处理来自Auth0的响应并向用户提供反馈取决于你特定的编程语言和/或开发框架。
你必须知道的是
deny()
方法,会触发对你的回调URL的请求,将error
和error_description
的值作为表单数据,如下图所示。
在本节中,你将学习如何在示例应用程序中处理这个响应,该应用程序使用ASP.NET Core MVC编程模型和Auth0 ASP.NET Core Authentication SDK。
为了让样本应用程序的用户在试用期到期时有更好的体验,你必须。
- 在你的网络应用程序中添加一个试用期过期的专用页面。
- 捕捉访问被拒绝的错误,并在试用期结束后将用户重定向到这个专用页面。
添加一个试用期过期的页面
如前所述,该示例应用程序是用C#在.NET中构建的。它使用了ASP.NET Core MVC框架,所以本小节所描述的步骤是与这个开发框架严格相关的。这一步的目标是为你的应用程序添加一个网页,所以请随意调整这一步,以适应你喜欢的开发环境。
转到你下载样本应用程序的文件夹。然后,移动到 Views/Home
文件夹,并创建一个 TrialExpiration.cshtml
文件。将以下代码放入该文件。
@* Views/Home/TrialExpiration.cshtml *@
@{
ViewData["Title"] = "Trial Expiration";
}
<div class="text-center">
<h1>@ViewData["Title"]</h1>
<p>
Your trial period expired.<br>
Subscribe to premium access!
</p>
</div>
这是你的试用期结束页面的标记。
现在,移动到项目根目录下的Controllers
文件夹,将下面突出显示的代码加入到 HomeController.cs
文件中。
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using acme.Models;
namespace acme.Controllers;
public class HomeController : Controller
{
// ...existing code...
// 👇 new code
public IActionResult TrialExpiration()
{
return View();
}
// 👆 new code
}
这段代码在应用程序的布局中渲染了试用期满页面的标记。
捕捉拒绝访问的错误
现在,让我们启用示例应用程序,以捕捉拒绝访问的错误,并将用户重定向到已经创建的试用期页面。打开 Program.cs
文件,并应用以下代码片段中强调的修改。
using Auth0.AspNetCore.Authentication;
// 👇 new code
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
// 👆 new code
var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddAuth0WebAppAuthentication(options => {
options.Domain = builder.Configuration["Auth0:Domain"];
options.ClientId = builder.Configuration["Auth0:ClientId"];
options.Scope = "openid profile email";
// 👇 new code
options.OpenIdConnectEvents = new OpenIdConnectEvents()
{
OnMessageReceived = (context) => {
if (context.ProtocolMessage.Error == "access_denied" &&
context.ProtocolMessage.ErrorDescription == "trial_expiration") {
context.HandleResponse();
context.Response.Redirect("/Home/TrialExpiration");
}
return Task.CompletedTask;
}
};
// 👆 new code
});
builder.Services.AddControllersWithViews();
// ...existing code...
新代码为OpenID Connect事件添加了一个处理程序OnMessageReceived
。这个处理程序只是检查收到的错误是access_denied
,错误描述是trial_expiration
。在这种情况下,它将用户重定向到试用期满的页面。
现在,停止你正在运行的应用程序并重新启动它。结果,用户将看到以下页面,而不是之前显示的错误页面。
在现实世界中,试用期满的页面应该提供更好的用户体验,例如,一个注册高级访问的表格和任何其他可以帮助用户继续使用你的应用程序服务的信息。
总结
回顾一下,你从一个已经与Auth0集成的即用型示例应用程序开始,并通过Auth0仪表板添加了几个动作。
- 开始试用期动作,在用户注册应用程序时,即在用户注册前的流程中,将试用期的到期日与用户联系起来。
- 检查试用期行动,在用户登录时,即在登录流程中,验证当前日期是否超过有效期。
这两个简单的动作为处理样本应用程序的试用期功能准备了基础设施。最后,为了改善用户体验,你创建了一个页面,当用户的试用期过期时,在那里登陆用户。
通过探索这个例子,我希望你现在对Auth0 Actions允许你做什么以及你如何定制标准的Auth0集成行为有了更好的了解。