欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

登录验证-过滤器(黑马学习笔记)

最编程 2024-03-01 09:41:13
...

分析

我们需要使用过滤器Filter来完成案例我们需要使用过滤器Filter来完成案例

我们先来回顾下前面分析过的登录校验的基本流程:

    ● 要进入到后台管理系统,我们必须先完成登录操作,此时就需要访问登录接口login。

————————————————————————————————————————

    ● 登录成功之后,我们会在服务端生成一个JWT令牌,并且把JWT令牌返回给前端,前端会将JWT令牌存储下来。

————————————————————————————————————————

    ● 在后续的每一次请求当中,都会将JWT令牌携带到服务端,请求到达服务端之后,要想去访问对应的业务功能,此时我们必须先要校验令牌的有效性。

————————————————————————————————————————

    ● 对于校验令牌的这一块操作,我们使用登录校验的过滤器,在过滤器当中来校验令牌的有效性。 如果令牌是无效的,就响应一个错误的信息,也不会再去放行访问对应的资源了。如果令牌存在,并且它是有效的,此时就会放行去访问对应的web资源,执行相应的业务操作。

大概清楚了在Filter过滤器的实现步骤了,那在正式开发登录校验过滤器之前,我们思考两个问题:

    1.所有的请求,拦截到了之后,都需要校验令牌吗?

        ○ 答案:登录请求例外

    2.拦截到请求后,什么情况下才可以放行,执行业务操作?

        ○ 答案:有令牌,且令牌校验通过(合法);否则都返回未登录错误结果

具体流程

我们要完成登录校验,主要是利用Filter过滤器实现,而Filter过滤器的流程步骤:

基于上面的业务流程,我们分析出具体的操作步骤:

    1.获取请求url

    2.判断请求url中是否包含login,如果包含,说明是登录操作,放行

    3.获取请求头中的令牌(token)

    4.判断令牌是否存在,如果不存在,返回错误结果(未登录)

    5.解析token,如果解析失败,返回错误结果(未登录)

    6.放行

代码实现

分析清楚了以上的问题后,我们就参照接口文档来开发登录功能了,登录接口描述如下:

    ● 基本信息

请求路径:/login

请求方式:POST

接口描述:该接口用于员工登录Tlias智能学习辅助系统,登录完毕后,系统下发JWT令牌。 

    ● 请求参数

       参数格式:application/json

       参数说明:

名称 类型 是否必须 备注
username string 必须 用户名
password string 必须

密码

        请求数据样例:

{
	"username": "jinyong",
    "password": "123456"
}

    ● 响应数据

       参数格式:application/json

       参数说明:

名称 类型 是否必须 默认值 备注 其他信息
code number 必须 响应码,1成功;0失败
msg string 非必须 提示信息
data string 必须 返回的数据,jwt令牌

       响应数据样例:

{
  "code": 1,
  "msg": "success",
  "data": "eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoi6YeR5bq4IiwiaWQiOjEsInVzZXJuYW1lIjoiamlueW9uZyIsImV4cCI6MTY2MjIwNzA0OH0.KkUc_CXJZJ8Dd063eImx4H9Ojfrr6XMJ-yVzaWCVZCo"
}

    ● 备注说明

       用户登录成功后,系统会自动下发JWT令牌,然后在后续的每次请求中,都需要在请求头               header中携带到服务端,请求头的名称为 token ,值为 登录时下发的JWT令牌。

       如果检测到用户未登录,则会返回如下固定错误信息:

{
	"code": 0,
	"msg": "NOT_LOGIN",
	"data": null
}

登录校验过滤器:LoginCheckFilter

@Slf4j
@WebFilter(urlPatterns = "/*") //拦截所有请求
public class LoginCheckFilter implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
        //前置:强制转换为http协议的请求对象、响应对象 (转换原因:要使用子类中特有方法)
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        //1.获取请求url
        String url = request.getRequestURL().toString();
        log.info("请求路径:{}", url); //请求路径:http://localhost:8080/login


        //2.判断请求url中是否包含login,如果包含,说明是登录操作,放行
        if(url.contains("/login")){
            chain.doFilter(request, response);//放行请求
            return;//结束当前方法的执行
        }


        //3.获取请求头中的令牌(token)
        String token = request.getHeader("token");
        log.info("从请求头中获取的令牌:{}",token);


        //4.判断令牌是否存在,如果不存在,返回错误结果(未登录)
        if(!StringUtils.hasLength(token)){
            log.info("Token不存在");

            Result responseResult = Result.error("NOT_LOGIN");
            //把Result对象转换为JSON格式字符串 (fastjson是阿里巴巴提供的用于实现对象和json的转换工具类)
            String json = JSONObject.toJSONString(responseResult);
            response.setContentType("application/json;charset=utf-8");
            //响应
            response.getWriter().write(json);

            return;
        }

        //5.解析token,如果解析失败,返回错误结果(未登录)
        try {
            JwtUtils.parseJWT(token);
        }catch (Exception e){
            log.info("令牌解析失败!");

            Result responseResult = Result.error("NOT_LOGIN");
            //把Result对象转换为JSON格式字符串 (fastjson是阿里巴巴提供的用于实现对象和json的转换工具类)
            String json = JSONObject.toJSONString(responseResult);
            response.setContentType("application/json;charset=utf-8");
            //响应
            response.getWriter().write(json);

            return;
        }


        //6.放行
        chain.doFilter(request, response);

    }
}

在上述过滤器的功能实现中,我们使用到了一个第三方json处理的工具包fastjson。我们要想使用,需要引入如下依赖:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.76</version>
</dependency>

登录校验的过滤器我们编写完成了,接下来我们就可以重新启动服务来做一个测试:

测试前先把之前所编写的测试使用的过滤器,暂时注释掉。直接将@WebFilter注解给注释掉即可。

    ● 测试1:未登录是否可以访问部门管理页面

       首先关闭浏览器,重新打开浏览器,在地址栏中输入:http://localhost:9528/#/system/dept

       由于用户没有登录,登录校验过滤器返回错误信息,前端页面根据返回的错误信息结果,自动跳转到登录页面了

    ● 测试2:先进行登录操作,再访问部门管理页面

       登录校验成功之后,可以正常访问相关业务操作页面

推荐阅读