尚筹网02-后台-管理员登录

186 阅读3分钟

一、识别操作系统人的身份

1.目标

识别操作系统的人的身份,控制它的行为

2.思路

image.png

3.代码

3.1 创建工具方法执行MD5加密

image.png

传进一个字符串,返回一个加密的字符串

/**
 * 对明文进行MD5加密
 * @param source 传入的明文字符串
 *
 * */
public static String md5(String source) {
    // 1.判断source是否有效
    if (source == null || source.length() == 0) {
        // 2.如果不是有效字符串,抛出异常
        throw new RuntimeException(CrowdConstant.MESSAGE_STRING_INVALIDATE);
    }

    try {
        // 3.获取MessageDigest
        //algorithm:翻译算法
        String algorithm = "md5";
        MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
        // 4.获取明文字符串的字节数组
        byte[] inputs = source.getBytes();
        // 5.执行加密
        byte[] output = messageDigest.digest(inputs);
        // 6.创建bigInteger对象
        int signum = 1;
        BigInteger bigInteger = new BigInteger(signum, output);
        // 7.将bigInteger转为16进制字符串
        int radix = 16;
        String encode = bigInteger.toString(radix).toUpperCase();


        return encode;

    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    return null;
}

3.2创建自定义的登录失败异常

image.png

/**
 * @author hejinjie
 * 创建登录失败的异常处理类
 * */

public class LoginFailedException extends RuntimeException{
    public static final long serialVersionUID = 1L;

    public LoginFailedException() {
        super();
    }

    public LoginFailedException(String message) {
        super(message);
    }

    public LoginFailedException(String message, Throwable cause) {
        super(message, cause);
    }

    public LoginFailedException(Throwable cause) {
        super(cause);
    }

    protected LoginFailedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

3.3 在异常处理器类中增加登录失败异常的处理

image.png

/**
 * 表示捕获到登录异常类型的异常对象由当前方法处理
 * */
@ExceptionHandler(value = LoginFailedException.class)
public ModelAndView resolveLoginFailedException(
        LoginFailedException exception,
        HttpServletRequest request,
        HttpServletResponse response
) throws IOException {
    // 只是指定当前异常对应的页面即可
    String viewName = "admin-login";
    return commonResolveException(viewName, exception, request, response);
}

3.4 在登录页面显示异常消息

image.png

3.5 Controller方法

image.png

/**
 *     登录功能
 * @param LoginAcct:前端传来的用户名
 * @param userPswd:前端传来的密码
 * */
@RequestMapping("/admin/do/login.html")
public String doLogin(@RequestParam String LoginAcct,
                      @RequestParam String userPswd,
                      HttpSession session){
    System.out.println("LoginAcct="+LoginAcct);

    //调用service执行登录检查
    //如果能够返回admin说明登录成功,否则登录失败抛出异常
    Admin admin = adminService.getAdminByLoginAcct(LoginAcct,userPswd);
    System.out.println("admin="+admin);
    // 登录成功后将admin对象放入session作用域中
    session.setAttribute(CrowdConstant.ATTR_NAME_LOGIN_ADMIN,admin);
    // 避免跳转到后台主页面再刷新浏览器导致重复提交表单,重定向到目标页面
    return "redirect:/admin/do/main.html";
}

3.6 Service方法

用的是QBZ查询

image.png

/**
 * 用户登录验证方法
 * */
@Override
public Admin getAdminByLoginAcct(String loginAcct, String userPswd) {
    System.out.println("表单传入loginAcct="+loginAcct+",密码="+userPswd);
    // 1.创建AdminExample对象
    AdminExample adminExample = new AdminExample();
    // 2.创建Criteria对象
    Criteria criteria = adminExample.createCriteria();
    // 3.再Criteria对象中封装查询条件
    criteria.andLoginAcctEqualTo(loginAcct);
    // 4.调用AdminMapper的方法执行查询
    List<Admin> list = mapper.selectByExample(adminExample);
    // 5.判断Admin对象是否为NULL
    if (list==null||list.size()==0){
        throw new LoginFailedException(CrowdConstant.MESSAGE_LOGIN_FAILED);
    }
    Admin admin = list.get(0);
    System.out.println("list.get(0)="+admin);
    // 6.如果为Null则抛出异常

    // 7.如果不为null则将数据库密码从Admin对象中取出
    String adminUserPswd = admin.getUserPswd();
    System.out.println("数据库的tom密码="+adminUserPswd);
    // 8.将表单提交的明文密码进行加密
    String md5 = CrowdUtil.md5(userPswd);
    // 9.对密码进行比较
    if (!(Objects.equals(md5,adminUserPswd))){
        throw new LoginFailedException(CrowdConstant.MESSAGE_LOGIN_FAILED);
    }
    //如果一致返回admin
    return admin;
}

3.7 测试

image.png image.png

image.png

3.8 抽取后台主页面公共部分

目的:省去了大量重复代码

image.png

image.png

创建JSP模板

image.png

二、拦截器:登录状态检查

1.目标

将部分资源保护起来,让没有登录的请求不能访问

2.思路

image.png 拦截器的使用:

  • 1.创建拦截器类
  • 2.注册拦截器类
  • 3.完善配套的异常映射

3.代码

3.1创建自定义异常

image.png

/**
 * @author hejinjie
 * 表示用户还没有登录就访问受保护资源异常
 * */

public class AccessForbiddenException extends RuntimeException{
    private static final long serialVersionUID = 2L;

    public AccessForbiddenException() {
        super();
    }

    public AccessForbiddenException(String message) {
        super(message);
    }

    public AccessForbiddenException(String message, Throwable cause) {
        super(message, cause);
    }

    public AccessForbiddenException(Throwable cause) {
        super(cause);
    }

    protected AccessForbiddenException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

3.2创建拦截器类

image.png

public class LoginInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        // 1.获取session对象
        HttpSession session = request.getSession();
        // 2.尝试获取Admin对象
        Admin admin = (Admin) session.getAttribute(CrowdConstant.ATTR_NAME_LOGIN_ADMIN);

        // 3.判断admin是否为空
        if (admin==null){
            // 4.抛出异常
            throw new RuntimeException(CrowdConstant.MESSAGE_LOGIN_FORBIDDEN);
        }
        // 5.否则说明Admin对象不为null,放行
        return true;
    }
}

3.3注册拦截器类

image.png

<!-- 4.注册拦截器-->
<mvc:interceptors>
    <mvc:interceptor>
        <!-- mvc:mapping 配置要拦截的资源-->
        <!--/*对应一层路径,如/aaa-->
        <!--/**对应多层路径,如/aaa/bbb或者/aaa/bbb/ccc或/aaa/bbb/ccc/ddd-->
        <mvc:mapping path="/**"/>
        <!-- mvc:exclude-mapping 配置不拦截的资源-->
        <mvc:exclude-mapping path="/admin/do/login/page.html"/>
        <mvc:exclude-mapping path="/admin/do/login.html"/>
        <mvc:exclude-mapping path="/admin/do/logout.html"/>
        <!--配置拦截器的类-->
        <bean class="com.hejinjie.crowd.mvc.interceptor.LoginInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

3.4完善配套的异常映射

3.4.1基于XML的异常映射

image.png image.png

3.4.2基于注解的异常映射

image.png