如何基于用户套餐/角色限制使用量,结合Identity实现用量管控?
实现方案
步骤1:扩展存储结构适配动态套餐配置
你可以直接基于现有Identity体系扩展表结构,满足后台动态编辑套餐的需求:
- 新增
UserPackages套餐配置表,字段至少包含:套餐ID、套餐名称、单用户相册最大上传数(高级套餐统一存-1代表无限制)、启用状态,后台新增/编辑套餐时只需要操作这张表即可,不需要修改代码 - 在Identity默认的
AspNetUsers表扩展PackageId外键字段,关联用户所属的套餐等级
步骤2:实现自定义授权策略(兼容现有Identity体系)
推荐用ASP.NET Core原生的基于策略的授权机制,和你当前用的Authorize属性使用逻辑完全兼容:
- 先创建用量限制需求类
public class PhotoUploadLimitRequirement : IAuthorizationRequirement { }
- 实现授权校验逻辑,自动关联用户套餐和当前用量
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(); } } }
- 在
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
相关产品推荐
相关产品推荐

