从零开始搭建前后端分离的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的项目框架之九如何进行用户权限控制
在一般的前后端分离的web系统开发中,在服务端除了对用户数据的缓存之外,往往在某些接口上,还涉及到对用户权限的限制,有的接口只能让具有特定权限的人员才可以访问。
这样以来就可以加强系统的安全性,在前面章节中简单讲了 MemoryCache与redis缓存的使用 ,方便将用户数据缓存到服务器上在需要的时候快速取出使用与验证,
下面我们就讲讲如何进行用户权限的验证,以下将是一个简单的示例,可以根据需求自行调节,权限组也可以根据数据库配置实现等等
在前面已经有 Token 验证 以及 用户数据 缓存的情况下,新建 用户验证 的 过滤器 类 UserAuthorize 继承 ActionFilterAttribute 属性
/// <summary>/// 用户权限验证/// </summary>public class UserAuthorize : ActionFilterAttribute {public UserAuthorize() { }public List<long> Popedoms { get; set; }//驼峰命名 首字母大写/// <summary>/// 构造函数/// </summary>/// <param name="popedom">权限组</param>public UserAuthorize(params long[] popedom) { Popedoms = popedom.ToList(); }public override void OnActionExecuting(ActionExecutingContext filterContext) {//整个类是否设置了都可以访问if (filterContext.ActionDescriptor is ControllerActionDescriptor controllerActionDescriptor) {var isDefined = controllerActionDescriptor.MethodInfo.GetCustomAttributes(true) .Any(a => a.GetType() == typeof(AllowAnonymousAttribute));if (isDefined) {return; } }var user = UserCache.GetCurrentUser();//获取当前用户if (user != null && Popedoms?.Contains(user.PopedomId) == true) {return; }if (user == null) { filterContext.Result = new CustomHttpStatusCodeResult(200, 401, "授权已失效请重新登录"); }else{ filterContext.Result = new CustomHttpStatusCodeResult(200, 402, "您无权进行该操作,请联系管理员!"); } } }
涉及到的相关代码 在之前添加的 UserCache 类中添加代码如下: 完整代码,文章最下面有GitHub 地址
/// <summary>/// 获取当前用户/// </summary>/// <returns></returns>internal static UserDto GetCurrentUser() {var key = DemoWeb.HttpContext.Request.Headers["sid"];if (string.IsNullOrEmpty(key)) {return null; }var user = Get(key);if (string.IsNullOrEmpty(user)) {return null; }return user.ToNetType<UserDto>(); }
接下来 我们添加登录测试伪代码 然后将用户数据存进缓存 再调用添加了权限验证的接口,来验证权限验证是否可用,
新建用户相关控制器 UserController ,继承之前的用户基础控制器 BaseUserController ,要有权限验证,肯定得先登录,示例代码如下:
[Route("api/[controller]")]public class UserController : BaseUserController { [HttpPost, Route("login"),AllowAnonymous]//AllowAnonymous加上这一句 为任何用户可访问,在基础控制器中有设置public ActionResult Login() {//调用登录方法进行登录 在业务层处理 将登录成功的用户信息缓存 以及生成token//此处示例 为了方便就直接在控制器中编写var token = TokenManager.GenerateToken("测试token的生成"); Response.Headers["token"] = token;//Response.Headers["Access-Control-Expose-Headers"] = "token"; //需要同时设置 不然后者会冲突掉前者var user = new UserDto() { UserName = "Levy", Email = "levy_w_wang@qq.com", Age = 23, PopedomId = 999};var sessionId = Guid.NewGuid().ToString("N"); DemoWeb.HttpContext.Response.Headers["sid"] = sessionId; UserCache.Set(sessionId,user.ToJson()); DemoWeb.HttpContext.Response.Headers["Access-Control-Expose-Headers"] = "token,sid";//前后端分离 跨域的情况下 加上这句 前端才能拿到 sid 字段对应值 多个用英文逗号分隔return Succeed(user); }/// <summary>/// 用户权限为888 或者为 999 的才能访问/// </summary>/// <returns></returns>[HttpPost,Route("popedom"),UserAuthorize(888,999)]public ActionResult PopedomTest() {return Succeed("成功访问"); } }
运行程序,打开接口测试工具,先访问登录接口,然后将得到的 Token 和 sid 拿来 调用 权限测试接口 我们就可以得到如下结果:截图如下:
再然后调试登录,把登录的权限改为不在权限控制的值之类,再次拿着返回的sid 及 Token 来访问权限测试接口,就会得到如下结果:
这里只是做了一个简单权限验证测试,灵活运用需结合数据库及缓存,也可以根据权限设置好响应的过滤器等等方式。
有需要源码的可通过此 GitHub 链接拉取 觉得还可以的给个 start 和点个 下方的推荐哦