• ASP.NET Core CMS管理后台


    ASP.NET Core+LayUI+MySql CMS管理后台,主要功能包括 登录、修改密码,账号管理,菜单管理,角色权限管理等

    由于工作之外,抽时间写的,用于学习交流,请慎重用于生产环境

    项目概要

    CMS管理后台包含的功能有 登录、修改密码、账号管理(账号列表,添加,修改,删除,禁/启用,解锁)、菜单管理(菜单列表,添加,修改,删除,禁/启用)、角色权限管理(角色列表,添加,修改,删除,禁/启用,分配权限)等后台最基础的功能。

    CMS管理后台使用的ASP.NET Core MVC模式,LayUI做的前端页面,Mysql做的数据存储,Razor页面引擎

    登录加入图片验证码,验证码保存在Session中,Cookie+AES加密保存用户登录状态,密码使用MD5加密保存在数据库

    使用 AuthorizationFilter 过滤器判断用户的登录状态和操作权限,权限判断基于Controller和Action

    表单数据提交采用ajax提交,页面的展示与数据提交一般共用同一个 Action,

    1. 像添加、修改、分配权限等通过 if (!Request.Method.ToUpper().Equals("POST", StringComparison.OrdinalIgnoreCase) || !Request.HasFormContentType) 来区分是显示页面还是提交请求

    2. 像账号列表、菜单列表、权限列表等通过 if (id == null || !id.ToUpper().Equals("DATA", StringComparison.OrdinalIgnoreCase)) 来区分是显示页面还是返回数据列表

    使用依赖注入,面向切面来实现业务,减少藕尔,使代码也易于管理

    软件版本

    ASP.NET Core:2.1

    MySql:5.6

    LayUI:2.4.5

    jquery:3.3.1

    项目结构

    image

    image

    Database:数据库脚本,包括建库、建表、数据初始化等脚本

    Snai.CMS:代码目录

    wwwroot:js,css,image等静态文件

    Business:业务实现,登录,账号管理,角色管理,菜单管理等实现

    Common:公共基础的方法类库,加解密,AuthorizationFilter过滤器,验证码实现,时间戳,随机数,密码复杂度检查,系统一些常量等

    Controllers:控制器,加入了ControllerBase继承Controller,其他控制器继承ControllerBase,主要是 抽出GetLayoutModel(),再通过泛型 ToT<T>(ref T t) 方法,得到子类页面Model,简化控制器取 LayoutModel Model值

    DataAccess:数据库操作

    Entities:实体对象

    Models:模型

    Views:视图

     

    项目介绍

    一、CMS数据库 snai_cms

    数据表 管理员表(admins),菜单表(modules),角色表(roles),权限表(role_right)

    时间以utc时间戳保存,ORM使用EFCore操作数据库

    image

    二、登录

    登录的 用户名、密码、验证码 都正确才能登录成功,登录成功跳转到后台首页

    默认的用户名:snai,密码:snai2019

    如果在30分钟内,密码错误3次,将锁定账号30分钟,这里的时间和错误次数可以在appsettings.json配置

    "LogonSettings": {
         "ErrorCount": 3,  //错误次数
         "ErrorTime": 30,  //单位时间内错误的时间
         "LockMinute": 30  //锁定时间
       }

    每次登录不管成功还是失败都会刷新验证码,验证码保存在 Session,有效时间15分钟

    登录成功后,登录用户 Token(用户名,密码,随机码)通过 AES 加密保存在 Cookie 中,登录 Cookie 的有效期为关掉浏览器过期,AES加密密钥在appsettings.json配置

    "WebSettings": {
         "CipherKey": "wEd5cxs0xUZe6WBCTUFIMJIDRnLZYWG9",   //AES加密密钥
         "WebTitle": "CMS管理后台"  //管理后台名称
       }

    通过 AuthorizationFilter 过滤器判断登录和权限,除了登录和退出,其他页面和操作都需要登录和相应权限,权限判断是通过用户角色,Controller和Action 对应的菜单来判断

    image

    image

    三、登录信息和修改密码

    登录信息 主要显示当前登录IP和登录时间

    image

    修改密码  可以通过旧密码来修改密码,密码要求 至少6位,且必须是字母与(数字或特殊符号)组合

    image

    右上角,包括退出按钮,用于退出后台

    image

    四、后台设置

    后台设置包括 管理员管理,管理员管理包括 账号管理、菜单管理、角色管理

    image

    1、账号管理 主要包括 账号列表,添加,修改,删除,禁/启用,解锁等操作

    image

    2、菜单管理 主要包括 菜单列表,添加,修改,删除,禁/启用等操作

    image

    3、角色管理 主要包括 角色列表,添加,修改,删除,禁/启用,分配权限等操作

    image

    分配权限 除了登录和退出,其他页面和操作都需要权限

    image

     

    开发时的一些注意

    1. 注册HttpContext,用于在Controller之外的地方使用

         services.AddHttpContextAccessor();

    2. appsettings.json 中文乱码,如配置文件里有中文,保存时默认GB2312格式,改为UTF-8

    3. View 文件不编译 <MvcRazorCompileOnPublish>false</MvcRazorCompileOnPublish>

    4. View 使用Model

    @{
        ViewData.Model = new NoUserRoleModel()
        {
            PageTitle = "没有权限访问",
            WebTitle = "CMS管理后台"
        };
    }  

    5. Razor里的代码块html标签跨了代码段时,视图会报错

    如:下面这种写法就会报错

        @if(...){
            <li class='layui-nav-item'>
        }
            </li>
        正确写法
        @if(...){
            <li class='layui-nav-item'></li>
        }
        或
        @if(...){
            @Html.Raw("<li class='layui-nav-item'>")
        }
            @Html.Raw("</li>")

    6. 加基类控制器 ControllerBase : Controller,抽出GetLayoutModel(),再通过泛型 ToT<T>(ref T t) 方法,得到子类页面Model, 简化控制器取 LayoutModel Model值

    7. layui重新渲染后的单选按钮,选择后直接用 $("input[name='state']:checked").val() 是取不值的(用layui的表单取值不确定是否

    能取到)后面用layui监听事件,监听按钮选择修改原单选按钮选中状态,然后再用 $("input[name='state']:checked").val() 取值

        MA.layui.form.on('radio(state)', function (data) {
            if (data.value == 1) {
                MA.Form.state1.attr("checked", true);
                MA.Form.state2.attr("checked", false);
            } else {
                MA.Form.state1.attr("checked", false);
                MA.Form.state2.attr("checked", true);
            }
        });

    8. 对于checkbox提交,用 jquery 组合成数组提交

        var moduleIDs =[];   
        $("input[name='moduleIDs']:checked").each(function(){   
            moduleIDs.push($(this).val());   
        });
    
        //请求参数
        var params = {
            roleID: MRR.Form.roleID.val(),
            moduleIDs: moduleIDs 
        };

    9. 对于分配权限时checkbox选择与联动选择,也用的是layui监听事件MRR.layui.form.on('checkbox(moduleIDs)', function (data) {}); 来设置原checkbox的值

    对于联动后重新渲染checkbox用MRR.layui.form.render('checkbox'),要注意用prop而不用attr,$(this).prop("checked", false),否则已经做过选择复选框联动无效

    菜单层级

    后台配置

    --------管理员管理

    -----------------账号管理

    --------------------------添/删/改等账号

    Github源码地址:https://github.com/Liu-Alan/Snai.CMS

     
     
     
  • 相关阅读:
    Django用户认证系统(三)组与权限
    Django用户认证系统(二)Web请求中的认证
    Django用户认证系统(一)User对象
    Django QuerySet API文档
    带有Header的SOAP 请求
    环境的配置,就需要理解组件的原理和机制。
    Hotspot JVM的常用选项
    Java程序员必学的Hotspot JVM选项
    三大Java 虚拟机垃圾回收机制的比较(HotSpot, JRockit, IBM JVM)
    [原]使用Fiddler捕获java的网络通信数据
  • 原文地址:https://www.cnblogs.com/alan-lin/p/10731139.html
Copyright © 2020-2023  润新知