订阅期满应该怎么限制?
How should the restriction be done when the subscription period expires?
在 Rest Api SaaS 项目中使用 .Net Core 3.1.
开发
当用户的订阅到期(需要付费)时,采用什么样的方式比较好
我想到了2种方法,但我认为这两种方法都会有一些问题。
方法1)生成JWT时检查订阅状态,订阅期过后不生成JWT:
如果我用这个方法;
优点:由于不会给订阅到期的用户一个token,
他们将无法访问其他端点。
我认为这将非常安全,无需进行任何其他编码工作。
缺点:当我需要将用户重定向到支付页面时,
由于没有令牌,我将不得不为支付端点做一些特殊的工作。(例如:密码重置方法)
我会用查询字符串得到它,我想我可以为这个方法创建一个特殊的标记。
但我认为可能存在安全漏洞,因为我无法使用标准授权方法保护此进程?
方法2)即使订阅过期,也会生成jwt,但会限制会员:
如果我用这个方法;
优点:我可以毫无问题地使用我的标准授权方法
当我需要将用户定向到支付端点或另一个端点时。
我将与 jwt 一起使用,安全漏洞将大大减少。
缺点:我需要为订阅期已过的用户确定无法在应用程序上访问的端点
我将需要在中间件中编写一个工作服务,使它们无法访问。 (喜欢权限方法)
这都将进行额外的编码工作,并且每个端点都需要额外的工作。
这些是我的想法....
或其他解决方案...
我们应该如何限制订阅到期的用户以及我们应该如何操作?
非常感谢您的信息分享
我用方法二解决了我上面问的问题
我想解释一下我是怎么做到的,因为我认为这可能会对以后研究这个问题的人有所帮助。
我在方法二中说了,jwt已经生成但是成员限制。
首先,在生成令牌时,我设置声明他们是否有订阅。
....
new Claim(JwtClaimIdentifier.HasSubscription, hasSubscription)
这里就不详细解释了。标准声明。
订阅控制
[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**);
}
}
我添加了一个覆盖订阅控制的属性。
例如;要在控制器或方法中使用它,我需要在检查基础上的订阅时覆盖它。
使用控制器
[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”。
希望它对您的业务有益...
在 Rest Api SaaS 项目中使用 .Net Core 3.1.
开发当用户的订阅到期(需要付费)时,采用什么样的方式比较好
我想到了2种方法,但我认为这两种方法都会有一些问题。
方法1)生成JWT时检查订阅状态,订阅期过后不生成JWT:
如果我用这个方法;
优点:由于不会给订阅到期的用户一个token, 他们将无法访问其他端点。 我认为这将非常安全,无需进行任何其他编码工作。
缺点:当我需要将用户重定向到支付页面时, 由于没有令牌,我将不得不为支付端点做一些特殊的工作。(例如:密码重置方法) 我会用查询字符串得到它,我想我可以为这个方法创建一个特殊的标记。 但我认为可能存在安全漏洞,因为我无法使用标准授权方法保护此进程?
方法2)即使订阅过期,也会生成jwt,但会限制会员:
如果我用这个方法;
优点:我可以毫无问题地使用我的标准授权方法 当我需要将用户定向到支付端点或另一个端点时。 我将与 jwt 一起使用,安全漏洞将大大减少。
缺点:我需要为订阅期已过的用户确定无法在应用程序上访问的端点 我将需要在中间件中编写一个工作服务,使它们无法访问。 (喜欢权限方法) 这都将进行额外的编码工作,并且每个端点都需要额外的工作。
这些是我的想法....
或其他解决方案...
我们应该如何限制订阅到期的用户以及我们应该如何操作?
非常感谢您的信息分享
我用方法二解决了我上面问的问题
我想解释一下我是怎么做到的,因为我认为这可能会对以后研究这个问题的人有所帮助。
我在方法二中说了,jwt已经生成但是成员限制。
首先,在生成令牌时,我设置声明他们是否有订阅。
....
new Claim(JwtClaimIdentifier.HasSubscription, hasSubscription)
这里就不详细解释了。标准声明。
订阅控制
[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**);
}
}
我添加了一个覆盖订阅控制的属性。
例如;要在控制器或方法中使用它,我需要在检查基础上的订阅时覆盖它。
使用控制器
[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”。
希望它对您的业务有益...