C# 当订阅期到期时,应如何进行限制?
在使用.Net Core 3.1开发的Rest ApiSaaS项目中 当用户的订阅到期(需要付费)时,采用哪种方式更好 我想到了两种方法,但我认为这两种方法都会有一些问题 方法1)在生成JWT期间检查订阅状态,如果订阅期已过,则不生成JWT: 如果我使用这种方法 优势:由于令牌未提供给订阅到期的用户, 他们将无法访问其他端点。 我认为这将在不做任何其他编码工作的情况下非常安全地工作 缺点:当我需要将用户重定向到付款页面时, 我将不得不为支付端点做一项特殊的工作,因为没有令牌。(例如:密码重置方法) 我将使用查询字符串获得它,我想我可以为这个方法创建一个特殊的标记。 但我认为可能存在安全漏洞,因为我无法用标准授权方法保护此进程 方法2)即使订阅过期,也会生成jwt,但会员资格将受到限制: 如果我使用这种方法 优点:我可以毫无问题地使用我的标准授权方法 当我需要将用户引导到支付端点或其他端点时。 我将与jwt一起使用,安全漏洞将大大减少 缺点:我需要为订阅期过期的用户确定无法在应用程序上访问的端点 我需要在中间件中编写一个工作服务,使它们无法访问。(喜欢使用许可方法) 这两者都需要额外的编码工作,每个端点都需要额外的工作 这是我的想法 或其他解决方案 我们应该如何限制其订阅过期的用户,以及我们应该如何采取行动C# 当订阅期到期时,应如何进行限制?,c#,asp.net-core-webapi,payment,saas,C#,Asp.net Core Webapi,Payment,Saas,在使用.Net Core 3.1开发的Rest ApiSaaS项目中 当用户的订阅到期(需要付费)时,采用哪种方式更好 我想到了两种方法,但我认为这两种方法都会有一些问题 方法1)在生成JWT期间检查订阅状态,如果订阅期已过,则不生成JWT: 如果我使用这种方法 优势:由于令牌未提供给订阅到期的用户, 他们将无法访问其他端点。 我认为这将在不做任何其他编码工作的情况下非常安全地工作 缺点:当我需要将用户重定向到付款页面时, 我将不得不为支付端点做一项特殊的工作,因为没有令牌。(例如:密码重置方法
非常感谢您的信息共享。我用方法2解决了上面的问题。 我想解释一下我是如何做到的,因为我认为这可能会帮助那些将来调查这个问题的人 我在方法2中说过,jwt已经生成了,但成员资格受到限制
首先,在生成令牌时,我设置声明是否有订阅
....
new Claim(JwtClaimIdentifier.HasSubscription, hasSubscription)
我在此不作详细解释。标准索赔
订阅控制
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public sealed class SubscriptionRequiredAttribute : TypeFilterAttribute
{
public SubscriptionRequiredAttribute()
: base(typeof(SubscriptionFilter)) { }
}
--
--
我添加了一个覆盖订阅控制的属性
比如,;在控制器或方法中使用它,在检查base上的订阅时需要覆盖该控制器或方法
使用控制器
[SubscriptionRequired]
public class FooController
{
public async Task<IActionResult> FooMethodOne(){...}
public async Task<IActionResult> FooMethodTwo(){...}
[AllowWithoutSubscription]
public async Task<IActionResult> FooMethodThree(){...}
}
[需要订阅]
公共类FooController
{
公共异步任务FooMethodOne(){…}
公共异步任务FooMethodTwo(){…}
[AllowWithOutscription]
公共异步任务FooMethodThree(){…}
}
虽然上面的FooMethodOne和FooMethodTwo需要订阅,但FooMethodThree将在没有订阅的情况下工作
同样,所有控件都称为“AllowWithSubscription”。
它也可以在方法中称为“SubscriptionRequired”
希望它能为您的业务带来好处…JSON web令牌用于身份验证。用户的订阅是否过期将是一个授权问题,因此应单独处理。
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(){...}
}