专栏首页DotNet程序园搭建前后端分离的NetCore2.2+Vue

搭建前后端分离的NetCore2.2+Vue

从零开始搭建前后端分离的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 和点个 下方的推荐哦~~谢谢!

下一篇可能会讲到如何将数据库访问封装基础方法来方便使用或者常用加密等~

------------------------------------------------------------------------------------------------------------------------------------------------------------- 学习本是一个不断模仿、练习、创新、超越的过程。由于博主能力有限,文中可能存在描述不正确,欢迎指正、补充!感谢您的阅读。 -------------------------------------------------------------------------------------------------------------------------------------------------------------

作者:Levy-伟

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

本文分享自微信公众号 - DotNet程序园(dotnetblog)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-11-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • java自测心得、技术选型和实现方式

    程序员自测是很重要的一个环节,我认同测试驱动开发的理念,经过一段时间的测试代码的编写,发现测试代码需要保证几点,1.测试代码可重复跑,不能跑过一次,改了数据库数...

    逝兮诚
  • Spark系列——关于 mapPartitions的误区

    今天 Review 了一下同事的代码, 发现其代码中有非常多的 mapPartitions, 问其原因,他说性能比 map 更好。 我说为什么性能好呢? ...

    solve
  • Spark系列 —— 各类算子详解(一)

    本文主要是一篇总结性文章, 将列举绝大部分的 Spark Transformation算子及其使用方法 和一些使用场景。

    solve
  • 钢铁B2B电商案例:供应链金融如何解决供应链金融痛点

    区块链是一种按照时间顺序将数据块以特定的顺序相连的方式组合成的链式数据结构,其上存储了系统诞生以来所有交易的记录。区块链上的数据由全网节点共同维护并共同存储,同...

    宜信技术学院
  • select into 和 insert int select

    zucchiniy
  • 大数据可视洞察Davinci的安装与配置攻略

    Davinci既可作为公有云/私有云独立使用,也可作为可视化插件集成到三方系统。用户只需在可视化UI上简单配置即可服务多种数据可视化应用,并支持高级交互/行业分...

    宜信技术学院
  • in 和 exists 的不同

    in 是把外表和内表做 hash 连接,而 exists 是对外表作 loop 循环,每次 loop 循环再对内表进行查询,一直以来认为 exists 比 in...

    zucchiniy
  • 事务处理(二) - 数据库事务

    事务的作用是将一系列操作作为一个整体,一但其中出现问题,会回滚到事务的开始状态。即事务维护了数据的完整性和一致性。

    逝兮诚
  • 亿级数据mysql优化

    用户分析系统以用户的心跳数据为依据,统计查询用户的各种情况。心跳数据很多,经过去重,去无效,数据量还是在2亿/月的水平。普通的查询在这个量级的数据库上根本查不出...

    逝兮诚
  • 连接Oracle数据库的工具,

    Oracle全称 Oracle Database 是甲骨文公司的一款关系型数据库管理系统,他在数据库领域是处于领先的地位的产品,可以说Oracle数据库系统是目...

    北京锐智互动

扫码关注云+社区

领取腾讯云代金券