You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于用户套餐/角色限制使用量,结合Identity实现用量管控?

实现方案

步骤1:扩展存储结构适配动态套餐配置

你可以直接基于现有Identity体系扩展表结构,满足后台动态编辑套餐的需求:

  • 新增UserPackages套餐配置表,字段至少包含:套餐ID、套餐名称、单用户相册最大上传数(高级套餐统一存-1代表无限制)、启用状态,后台新增/编辑套餐时只需要操作这张表即可,不需要修改代码
  • 在Identity默认的AspNetUsers表扩展PackageId外键字段,关联用户所属的套餐等级

步骤2:实现自定义授权策略(兼容现有Identity体系)

推荐用ASP.NET Core原生的基于策略的授权机制,和你当前用的Authorize属性使用逻辑完全兼容:

  1. 先创建用量限制需求类
public class PhotoUploadLimitRequirement : IAuthorizationRequirement
{
}
  1. 实现授权校验逻辑,自动关联用户套餐和当前用量
public class PhotoUploadLimitHandler : AuthorizationHandler<PhotoUploadLimitRequirement>
{
    private readonly IUserPhotoService _userPhotoService; // 自行实现的相册服务,用于查询当前用户已上传图片数量
    private readonly IUserPackageService _userPackageService; // 自行实现的套餐服务,用于查询用户所属套餐的上传上限

    public PhotoUploadLimitHandler(IUserPhotoService userPhotoService, IUserPackageService userPackageService)
    {
        _userPhotoService = userPhotoService;
        _userPackageService = userPackageService;
    }

    protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PhotoUploadLimitRequirement requirement)
    {
        // 获取当前登录用户ID
        var userId = context.User.FindFirstValue(ClaimTypes.NameIdentifier);
        if (string.IsNullOrEmpty(userId))
        {
            context.Fail();
            return;
        }

        // 查询用户套餐的上传上限
        var uploadLimit = await _userPackageService.GetUserUploadLimitAsync(userId);
        // 上限为-1代表无限制,直接通过校验
        if (uploadLimit == -1)
        {
            context.Succeed(requirement);
            return;
        }

        // 查询当前用户已上传的图片数量
        var uploadedCount = await _userPhotoService.GetUserUploadedCountAsync(userId);
        // 剩余额度充足则通过,否则拒绝访问
        if (uploadedCount < uploadLimit)
        {
            context.Succeed(requirement);
        }
        else
        {
            context.Fail();
        }
    }
}
  1. 在Program.cs中注册授权策略和服务
// 注册自定义授权处理服务
builder.Services.AddScoped<IAuthorizationHandler, PhotoUploadLimitHandler>();
// 添加上传限制策略
builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("PhotoUploadLimit", policy =>
        policy.Requirements.Add(new PhotoUploadLimitRequirement()));
});

步骤3:在上传接口应用策略

和你原有Authorize属性的用法完全一致,直接指定策略即可:

[Authorize(Policy = "PhotoUploadLimit")]
[HttpPost("upload-photo")]
public async Task<IActionResult> UploadPhoto(IFormFile file)
{
    // 原有上传业务逻辑
}

可选优化

  • 如果对性能有要求,可以将套餐配置、用户已上传用量缓存1~5分钟,后台编辑套餐时主动清除对应缓存即可,减少频繁查询数据库的压力
  • 可单独提供用量查询接口,返回用户当前套餐上限、已用额度、剩余额度,方便前端做上传前提示和额度展示
  • 如果需要在非Controller层做校验,可以直接注入IAuthorizationService手动调用校验方法:
var authResult = await _authorizationService.AuthorizeAsync(User, null, "PhotoUploadLimit");
if (!authResult.Succeeded)
{
    // 返回错误或抛出权限不足异常
}

内容的提问来源于stack exchange,提问作者D.Fernandes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.15 23:36:09