java后端实现登录功能,并用过滤器验证

登录,退出功能

登录,退出功能的逻辑思路:
	 * 1. 密码md5加密
     * 2. 根据用户名查询数据库
     * 3. 比对密码
     * 4. 查看状态
     * 5. 将员工的id存放到session
  • 代码实现
@Slf4j  //输出日志方便调试
@RestController
@RequestMapping("/employee")
public class EmployeeController {

    //把创建的接口注入进来
    @Autowired
    private EmployeeService employeeService;
    /**
     * 员工登录
     *
     * @param request
     * @param employee
     * @return 处理逻辑:
     * 1. 密码md5加密
     * 2. 根据用户名查询数据库
     * 3. 比对密码
     * 4. 查看状态
     * 5. 将员工的id存放到session
     *
     * 完善登录功能,使没有登录的用户不能随意访问一些特定的界面
     * 1. 过滤器实现 √
     *      1.1自定义过滤器
     *      1.2加入注解
     *      1.3完善过滤器的逻辑
     *          1.3.1获取本次请求的uri
     *          1.3.2判断本次请求是否需要处理
     *          1.3.3判断登录状态
     * 2. 拦截器
     */

@PostMapping("/login")
//将员工对象的id存储到session,以方便获取登录对象
public R<Object> login(HttpServletRequest request, @RequestBody Employee employee){
    //1.密码加密处理
    String password = employee.getPassword();
    password = DigestUtils.md5DigestAsHex(password.getBytes());

    //2.根据用户输入名字,查数据库信息,根据页面提交的用户名username查询数据库,包装一个查询对象,
    LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(Employee::getUsername,employee.getUsername());
    Employee emp = employeeService.getOne(queryWrapper);
    //2.1 如果没有查询到就返回错误
    if(emp == null){
        return R.error("登录失败!");
    }

    //3.比对密码
    if(!emp.getPassword().equals(password)){
        return R.error("登录失败!");
    }

    //4.查看员工状态
    if(emp.getStatus()==0){
        return R.error("账号已禁用!");
    }

    //5.将用户id存放在session
    request.getSession().setAttribute("employee",emp.getId());
    return R.success(emp);
}

/**
 * 退出登录功能
 * @param request
 *
 * 需求分析:点击退出按钮像/employee/logout发送退出请求,请求方式为post
 * 代码开发:
 *  1. 创建controller,清理session中的用户信息
 *  2. 返回结果,页面跳转到登录姐界面
 * 功能测试
 */
@PostMapping("/logout")
public R<String> logout(HttpServletRequest request){
    //清理session中的用户信息
    request.getSession().removeAttribute("employee");
    return R.success("退出成功");
}

验证登录功能

完善登录功能,使没有登录的用户不能随意访问一些特定的界面
逻辑:
     * 1. 过滤器实现 √
     *      1.1自定义过滤器
     *      1.2加入注解
     *      1.3完善过滤器的逻辑
     *          1.3.1获取本次请求的uri
     *          1.3.2判断本次请求是否需要处理
     *          1.3.3判断登录状态
     * 2. 拦截器(不详细说明)
  • 代码实现
/**
 * 检用户是否已经完成登录,若没有则不可以进入特定的界面
 */
@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
@Slf4j
public class LoginCheckFilter implements Filter {
    //路径匹配器,支持通配符
    public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        //1.获取到本次请求的uri
        String requestURI = request.getRequestURI();

        log.info("拦截到请求:{}",requestURI);

        //2.判断本次请求是否需要处理
        //定义一些不需要可以放行的路径
        String[] urls = new String[]{
                "/employee/login",
                "/employee/logout",
                "/backend/**",
                "front/**"
        };
        boolean check = check(urls,requestURI);

        if(check){
            log.info("本次请求请求{}不要处理!",requestURI);
        //3.如果不需要处理直接放行
        filterChain.doFilter(request,response);
        return;
        }

        //4.判读用户是否已经登陆,直接放行
        if(request.getSession().getAttribute("employee")!=null){
            log.info("用户已登录,用户id为{}",request.getSession().getAttribute("employee"));
            filterChain.doFilter(request,response);
            return;
        }

        log.info("用户未登录");
        //5.如果未登录通过输出流的方式向客户端页面响应数据
        response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
        return;


}
    /**
     * 检查本次请求是否需要放行
     * @param requestURI
     * @return
     */
    public boolean check(String[] urls,String requestURI){
        for (String url : urls) {
            boolean match = PATH_MATCHER.match(url,requestURI);
            if(match){
                return true;
            }

        }
        return false;
}

}