【愚公系列】2023年04月 Java面面刷题系统-004.登录和权限校验


一、登录和权限校验

1. 登陆

1.1 登陆功能快速开发

1、找到项目webapp/login.jsp登陆页面,修改form表单提交的action路径

<form action="${pageContext.request.contextPath}/login?operation=login" method="post">
</form>

2、在后台UserServlet添加登陆的方法

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
    String operation = request.getParameter("operation");
    if("list".equals(operation)){
    
    
        this.list(request,response);
    }
    //中间省略
    else if("login".equals(operation)){
    
    
        this.login(request,response);
    }
}
private void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
    String email = request.getParameter("email");
    String pwd = request.getParameter("password");
    User user = userService.login(email,pwd);
    if(user != null) {
    
    
        request.getSession().setAttribute("loginUser", user);
        //跳转页面
        request.getRequestDispatcher("/WEB-INF/pages/home/main.jsp").forward(request, response);
    }else{
    
    
        response.sendRedirect(request.getContextPath()+"/login.jsp");
    }
}

3、在因为层接口UserService中添加登陆的方法

/**
     * 根据邮箱和密码登录
     * @param email
     * @param pwd
     * @return
     */
    User login(String email, String pwd);

4、在对应的实现类中去实现登陆方法

@Override
public User login(String email, String pwd) {
    
    
    SqlSession sqlSession = null;
    try{
    
    
        //1.获取SqlSession
        sqlSession = MapperFactory.getSqlSession();
        //2.获取Dao
        UserDao userDao = MapperFactory.getMapper(sqlSession,UserDao.class);
        //3.调用Dao层操作
        pwd = MD5Util.md5(pwd);
        return userDao.findByEmailAndPwd(email,pwd);
    }catch (Exception e){
    
    
        throw new RuntimeException(e);
        //记录日志
    }finally {
    
    
        try {
    
    
            TransactionUtil.close(sqlSession);
        }catch (Exception e){
    
    
            e.printStackTrace();
        }
    }
}

5、在UserDao接口中添加查询方法

User findByEmailAndPwd(@Param("email")String email, @Param("password")String pwd);

6、在UserDao.xml中添加查询

<select id="findByEmailAndPwd" parameterType="map" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List"/>
    from ss_user
    where email = #{email,jdbcType=VARCHAR} and password = #{password,jdbcType=VARCHAR}
</select>

7、修改/WEB-INF/pages/home/main.jsp内容区的路径

<!-- 内容区域 -->
<div class="content-wrapper">
    <iframe id="iframe" name="iframe"
            style="overflow:visible;"
            scrolling="auto"
            frameborder="no" height="100%" width="100%"
            src="${ctx}/system/user?operation=home"></iframe>
</div>

8、在后台UserServlet中添加方法

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
    String operation = request.getParameter("operation");
    if("list".equals(operation)){
    
    
        this.list(request,response);
    }
    //中间省略
    else if("home".equals(operation)){
    
    
        this.home(request,response);
    }
}
private void home(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
    request.getRequestDispatcher("/WEB-INF/pages/home/home.jsp").forward(request, response);
}

1.2 用户菜单控制数据准备

我们先来完成登陆后的注销操作,这是一套的

1、找到/WEB-INF/pages/home/header.jsp中找到注销,添加请求连接

<div class="pull-right">
    <a href="${ctx}/system/user?operation=logout" class="btn btn-default btn-flat">注销</a>
</div>

2、在后台UserServlet中添加对应的方法logout

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
    String operation = request.getParameter("operation");
    if("list".equals(operation)){
    
    
        this.list(request,response);
    }
    //中间的省略
    else if("login".equals(operation)){
    
    
        this.login(request,response);
    }else if("logout".equals(operation)){
    
    
        this.logout(request,response);
    }else if("home".equals(operation)){
    
    
        this.home(request,response);
    }
}
private void logout(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
    request.getSession().removeAttribute("loginUser");
    response.sendRedirect(request.getContextPath()+"/login.jsp");
}

3、在用户登陆的时候需要去查询该用户对应的角色对应的所有模块,因此需要在后台的UserServlet中修改用户登陆的方法,添加数据的查询

private void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
    String email = request.getParameter("email");
    String pwd = request.getParameter("password");
    User user = userService.login(email,pwd);
    if(user != null) {
    
    
        request.getSession().setAttribute("loginUser", user);
        //如果登录成功,加载该用户对应的角色对应的所有模块
        List<Module> moduleList = userService.findModuleById(user.getId());
        request.setAttribute("moduleList",moduleList);
        //跳转页面
        request.getRequestDispatcher("/WEB-INF/pages/home/main.jsp").forward(request, response);
    }else{
    
    
        response.sendRedirect(request.getContextPath()+"/login.jsp");
    }
}

4、在UserService接口中添加方法findModuleById

/**
     * 根据用户id查询所有可以操作的菜单对象
     * @param id 用户的id
     * @return
     */
    List<Module> findModuleById(String id);

5、在实现类中去实现该方法

@Override
public List<Module> findModuleById(String id) {
    
    
    SqlSession sqlSession = null;
    try{
    
    
        //1.获取SqlSession
        sqlSession = MapperFactory.getSqlSession();
        //2.获取Dao
        ModuleDao moduleDao = MapperFactory.getMapper(sqlSession,ModuleDao.class);
        //3.调用Dao层操作
        return moduleDao.findModuleByUserId(id);
    }catch (Exception e){
    
    
        throw new RuntimeException(e);
        //记录日志
    }finally {
    
    
        try {
    
    
            TransactionUtil.close(sqlSession);
        }catch (Exception e){
    
    
            e.printStackTrace();
        }
    }
}

6、在ModuleDao接口中添加查询方法findModuleByUserId

List<Module> findModuleByUserId(String id);

7、在ModuleDao.xml中添加对应的查询

<select id="findModuleByUserId" parameterType="java.lang.String" resultMap="BaseResultMap">
        /*userid->用户角色关系表->roleid->角色模块关系表->moduleid->module信息*/
        SELECT DISTINCT
          m.module_id, m.parent_id, m.name, m.ctype, m.state, m.curl, m.remark
        FROM
            ss_module AS m,
            ss_role_module AS rm,
            ss_role_user AS ru
        WHERE
            m.module_id = rm.module_id
        AND	rm.role_id = ru.role_id
        AND	ru.user_id = #{id,jdbcType=VARCHAR}
    </select>

至此:用户的角色对应的模块数据已查询出来了,后续就是要在页面进行控制展示

1.3 登陆用户菜单控制

1、找到/WEB-INF/pages/home/aside.jsp页面,添加用户菜单的展示

<!-- sidebar menu: : style can be found in sidebar.less -->
<ul class="sidebar-menu">
    <li class="header">菜单</li>

    <c:forEach items="${moduleList}" var="item">
        <c:if test="${item.ctype==0}">
            <li class="treeview">
                <a href="#">
                    <i class="fa fa-cube"></i> <span>${item.name}</span>
                    <span class="pull-right-container"><i class="fa fa-angle-left pull-right"></i></span>
                </a>
                <ul class="treeview-menu">
                    <c:forEach items="${moduleList}" var="item2">
                        <c:if test="${item2.ctype==1 && item2.parentId == item.id}">
                            <li id="${item2.id}">
                                <a οnclick="setSidebarActive(this)" href="${ctx}/${item2.curl}" target="iframe">
                                    <i class="fa fa-circle-o"></i>${item2.name}
                                </a>
                            </li>
                        </c:if>
                    </c:forEach>
                </ul>
            </li>
        </c:if>
    </c:forEach>

2.权限校验

2.1 获取请求url

1、创建过滤器:com.itheima.web.filters.AuthorFilter

@WebFilter(value = "/*")
public class AuthorFilter implements Filter {
    
    

    private FilterConfig filterConfig;

    /**
     * 初始化方法,获取过滤器的配置对象
     * @param filterConfig
     * @throws ServletException
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    
    
        this.filterConfig = filterConfig;
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
    
    
        //1.定义和协议相关的请求和响应对象
        HttpServletRequest request ;
        HttpServletResponse response;
        try{
    
    
            //2.把参数转换成协议相关的对象
            request = (HttpServletRequest)req;
            response = (HttpServletResponse)resp;

            //1.获取本次操作
            String url = request.getRequestURI();
            String queryString = request.getQueryString();

            //1.当前获取到的url:   /system/dept
            url = url.substring(1);
            //2.当前获取到的查询参数:operation=list       operation=toEdit&id=100
            int index = queryString.indexOf('&');
            if(index != -1){
    
    
                queryString = queryString.substring(0,index);
            }
            url = url + "?" + queryString;

            //2.获取到当前登录人允许的操作

            //3.比对本次操作是否在当前登录人允许的操作范围内
            //3.1如果允许,放行
            //3.2不允许跳转到非法访问页

            //6.放行
            chain.doFilter(request,response);
        }catch (Exception e){
    
    
            e.printStackTrace();
        }
    }

    @Override
    public void destroy() {
    
    
        //可以做一些清理操作
    }
}

2.2 获取登陆用户可执行操作

1、登陆成功后需要将用户的觉得对应的模块信息存放到session,找到UserServlet中的登陆方法login

private void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
    String email = request.getParameter("email");
    String pwd = request.getParameter("password");
    User user = userService.login(email,pwd);
    if(user != null) {
    
    
        request.getSession().setAttribute("loginUser", user);
        //如果登录成功,加载该用户对应的角色对应的所有模块
        List<Module> moduleList = userService.findModuleById(user.getId());
        request.setAttribute("moduleList",moduleList);

        //当前登录用户对应的可操作模块的所有url拼接成一个大的字符串
        StringBuffer sbf = new StringBuffer();
        for(Module m: moduleList){
    
    
            sbf.append(m.getCurl());
            sbf.append(',');
        }
        request.getSession().setAttribute("authorStr",sbf.toString());

        //跳转页面
        request.getRequestDispatcher("/WEB-INF/pages/home/main.jsp").forward(request, response);
    }else{
    
    
        response.sendRedirect(request.getContextPath()+"/login.jsp");
    }
}

2、修改AuthorFilter

@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
    
    
    //1.定义和协议相关的请求和响应对象
    HttpServletRequest request ;
    HttpServletResponse response;
    HttpSession session;
    try{
    
    
        //2.把参数转换成协议相关的对象
        request = (HttpServletRequest)req;
        response = (HttpServletResponse)resp;
        session = request.getSession();
        //1.获取本次操作
        String url = request.getRequestURI();
        //.css   .js    .png   .jpg   .index
        if(url.endsWith(".css")
           || url.endsWith(".js")
           || url.endsWith(".png")
           || url.endsWith(".jpg")
           || url.endsWith("index.jsp")
           || url.endsWith("login.jsp")){
    
    
            chain.doFilter(request,response);
            return;
        }
        String queryString = request.getQueryString();
        if(queryString.endsWith("operation=login")){
    
    
            chain.doFilter(request,response);
            return;
        }


        //1.当前获取到的url:   /system/dept
        url = url.substring(1);
        //2.当前获取到的查询参数:operation=list       operation=toEdit&id=100
        int index = queryString.indexOf('&');
        if(index != -1){
    
    
            queryString = queryString.substring(0,index);
        }
        url = url + "?" + queryString;

        //2.获取到当前登录人允许的操作
        String authorStr = session.getAttribute("authorStr").toString();
        //3.比对本次操作是否在当前登录人允许的操作范围内
        //3.1如果允许,放行
        //3.2不允许跳转到非法访问页

        //6.放行
        chain.doFilter(request,response);
    }catch (Exception e){
    
    
        e.printStackTrace();
    }
}

2.3 权限校验

1、更改AuthorFilter

@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
    
    
    HttpServletRequest request ;
    HttpServletResponse response;
    HttpSession session;
    try{
    
    
        request = (HttpServletRequest)req;
        response = (HttpServletResponse)resp;
        session = request.getSession();

        //1.获取本次操作
        String url = request.getRequestURI();
        //.css   .js    .png   .jpg   .index
        if(url.endsWith(".css")
           || url.endsWith(".js")
           || url.endsWith(".png")
           || url.endsWith(".jpg")
           || url.endsWith("index.jsp")
           || url.endsWith("unauthorized.jsp")
           || url.endsWith("login.jsp")){
    
    
            chain.doFilter(request,response);
            return;
        }
        String queryString = request.getQueryString();
        if(queryString.endsWith("operation=login")
           ||queryString.endsWith("operation=home")
           ||queryString.endsWith("operation=logout")){
    
    
            chain.doFilter(request,response);
            return;
        }
        //1.当前获取到的url:   /system/dept
        url = url.substring(1);
        //2.当前获取到的查询参数:operation=list       operation=toEdit&id=100
        int index = queryString.indexOf('&');
        if(index != -1){
    
    
            queryString = queryString.substring(0,index);
        }
        url = url + "?" + queryString;

        //2.获取到当前登录人允许的操作
        String authorStr = session.getAttribute("authorStr").toString();

        //3.比对本次操作是否在当前登录人允许的操作范围内
        if(authorStr.contains(url)){
    
    
            //3.1如果允许,放行
            chain.doFilter(request,response);
            return;
        }else{
    
    
            //3.2不允许跳转到非法访问页
            response.sendRedirect(request.getContextPath()+"/unauthorized.jsp");
        }
    }catch (Exception e){
    
    
        e.printStackTrace();
    }
}

2、对于页面上的元素,如果没有操作权限,我们直接让用户看不到即可,怎么操作呢?在页面上做一个判断,我们举一个例子,其他操作都是一样的

找到/WEB-INF/pages/system/user/list.jsp

<div class="btn-group">
    <c:if test="${sessionScope.authorStr.contains('system/user?operation=toAdd')}">
        <button type="button" class="btn btn-default" title="新建" οnclick='location.href="${ctx}/system/user?operation=toAdd"'><i class="fa fa-file-o"></i> 新建</button>
    </c:if>
    <button type="button" class="btn btn-default" title="删除" οnclick='deleteById()'><i class="fa fa-trash-o"></i> 删除</button>
    <button type="button" class="btn btn-default" title="刷新" οnclick="window.location.reload();"><i class="fa fa-refresh"></i> 刷新</button>
    <c:if test="${sessionScope.authorStr.contains('system/user?operation=userRoleList')}">
        <button type="button" class="btn btn-default" title="角色" οnclick="roleList()"><i class="fa fa-user-circle-o"></i> 角色</button>
    </c:if>
</div>

猜你喜欢

转载自blog.csdn.net/aa2528877987/article/details/129948307