登录校验-Filter
分析
使用过滤器Filter来完成案例当中的登录校验功能。
登录校验的基本流程:
- 要进入到后台管理系统,我们必须先完成登录操作,此时就需要访问登录接口login。
- 登录成功之后,我们会在服务端生成一个JWT令牌,并且把JWT令牌返回给前端,前端会将JWT令牌存储下来。
- 在后续的每一次请求当中,都会将JWT令牌携带到服务端,请求到达服务端之后,要想去访问对应的业务功能,此时我们必须先要校验令牌的有效性。
- 对于校验令牌的这一块操作,我们使用登录校验的过滤器,在过滤器当中来校验令牌的有效性。如果令牌是无效的,就响应一个错误的信息,也不会再去放行访问对应的资源了。如果令牌存在,并且它是有效的,此时就会放行去访问对应的web资源,执行相应的业务操作。
具体流程
我们要完成登录校验,主要是利用Filter过滤器实现,而Filter过滤器的流程步骤:
基于上面的业务流程,我们分析出具体的操作步骤:
1. 获取请求url
2. 判断请求url中是否包含login,如果包含,说明是登录操作,放行
3. 获取请求头中的令牌(token)
4. 判断令牌是否存在,如果不存在,返回错误结果(未登录)
5. 解析token,如果解析失败,返回错误结果(未登录)
6. 放行
代码实现
基本信息
请求路径:/login
请求方式:POST
接口描述:该接口用于员工登录Tlias智能学习辅助系统,登录完毕后,系统下发JWT令牌。
请求参数
参数格式:application/json
参数说明:
请求数据样例:
~~~json
{
"username": "jinyong",
"password": "123456"
}
~~~
响应数据
参数格式:application/json
参数说明:
响应数据样例:
~~~json
{
"code": 1,
"msg": "success",
"data": "eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoi6YeR5bq4IiwiaWQiOjEsInVzZXJuYW1lIjoiamlueW9uZyIsImV4cCI6MTY2MjIwNzA0OH0.KkUc_CXJZJ8Dd063eImx4H9Ojfrr6XMJ-yVzaWCVZCo"
}
~~~
备注说明:
用户登录成功后,系统会自动下发JWT令牌,然后在后续的每次请求中,都需要在请求头header中携带到服务端,请求头的名称为 token ,值为 登录时下发的JWT令牌。
如果检测到用户未登录,则会返回如下固定错误信息:
~~~json
{
"code": 0,
"msg": "NOT_LOGIN",
"data": null
}
~~~
登录校验过滤器:LoginCheckFilter
~~~java
@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。我们要想使用,需要引入如下依赖:
```xml
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.76</version>
</dependency>
```
登录校验的过滤器我们编写完成了,接下来我们就可以重新启动服务来做一个测试:
测试1:未登录是否可以访问部门管理页面
首先关闭浏览器,重新打开浏览器,在地址栏中输入:http://localhost:90/#/system/dept
由于用户没有登录,登录校验过滤器返回错误信息,前端页面根据返回的错误信息结果,自动跳转到登录页面了
测试2:先进行登录操作,再访问部门管理页面
登录校验成功之后,可以正常访问相关业务操作页面