在 休息API 用开发的SaaS项目.Net 核心 3.1 .
当用户订阅到期(需要付费)时,采用什么样的方法比较好。
我想到了两种方法,但我认为这两种方法都会存在一些问题。
方法 1) 在 JWT 生成期间检查订阅状态,如果订阅期已过,则不生成 JWT:
如果我使用这种方法;
优势 : 由于订阅过期的用户不会获得 token ,
他们将无法访问其他端点。
我认为这将非常安全,而无需进行任何其他编码工作。
缺点 :当我需要将用户重定向到支付页面时,
由于没有 token ,我将不得不为支付端点做一项特殊的工作。(例如:密码重置方法)
我会用查询字符串来获取它,我想我可以为这个方法创建一个特殊的标记。
但我认为可能存在安全漏洞,因为我无法使用我的标准授权方法来保护这个过程?
方法 2) 即使订阅过期,也会生成 jwt,但会限制成员(member)资格:
如果我使用这种方法;
优势 : 我可以毫无问题地使用我的标准授权方法
当我需要将用户定向到支付端点或另一个端点时。
我将与 jwt 一起使用,安全漏洞将大大减少。
缺点 :我需要为订阅期已过的用户确定无法在应用程序上访问的端点
我需要在中间件中编写一个工作服务,这将使它们无法访问。 (喜欢权限方法)
这都会做额外的编码工作,每个端点都需要额外的工作。
这些是我的想法......
或者其他解决方案...
我们应该如何限制订阅过期的用户,我们应该如何操作?
非常感谢您的信息分享。
最佳答案
我使用方法 2 解决了我上面提出的问题。
我想解释一下我是如何做到的,因为我认为这可能会对将来调查这个问题的人有所帮助。
我在方法2中说,jwt已经生成但是成员受限。
首先,在生成 token 时,我会设置声明是否有订阅。
....
new Claim(JwtClaimIdentifier.HasSubscription, hasSubscription)
我在这里不详细解释。标准 claim 。订阅控制
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public sealed class SubscriptionRequiredAttribute : TypeFilterAttribute
{
public SubscriptionRequiredAttribute()
: base(typeof(SubscriptionFilter)) { }
}
——[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public sealed class AllowWithoutSubscriptionAttribute : Attribute
{
public AllowWithoutSubscriptionAttribute() { }
}
——public class SubscriptionFilter : IAuthorizationFilter
{
private bool AllowWithoutSubscription(AuthorizationFilterContext context)
{
var controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
bool allowWithoutSubscriptionForMethod = controllerActionDescriptor.MethodInfo.CustomAttributes.Any(x => x.AttributeType == typeof(AllowWithoutSubscriptionAttribute));
if (allowWithoutSubscriptionForMethod)
return true;
bool allowWithoutSubscriptionForController = controllerActionDescriptor.ControllerTypeInfo.CustomAttributes.Any(x => x.AttributeType == typeof(AllowWithoutSubscriptionAttribute));
if (allowWithoutSubscriptionForController)
return true;
return false;
}
public void OnAuthorization(AuthorizationFilterContext context)
{
if (AllowWithoutSubscription(context))
return;
var hasSubscription = context.HttpContext.User.Claims.First(x => x.Type == JwtClaimIdentifier.HasSubscription).Value.ToLower() == "true";
if (!hasSubscription)
context.Result = new BadRequestObjectResult(**ErrorCode**);
}
}
我添加了一个覆盖订阅控制的属性。例如;要在检查基础订阅时需要覆盖的 Controller 或方法中使用它。
使用 Controller
[SubscriptionRequired]
public class FooController
{
public async Task<IActionResult> FooMethodOne(){...}
public async Task<IActionResult> FooMethodTwo(){...}
[AllowWithoutSubscription]
public async Task<IActionResult> FooMethodThree(){...}
}
虽然上面的 FooMethodOne 和 FooMethodTwo 需要订阅,但 FooMethodThree 无需订阅即可工作。同样,所有控件都称为“AllowWithoutSubscription”。
它也可以在方法中称为“SubscriptionRequired”。
希望它有益于您的业务...
关于c# - 认购期满了该如何限制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62327478/