目录
思路
登录校验Filter-流程
步骤
流程图
登录校验Filter-代码
过滤器类
工具类
测试登录
登录接口功能请求
其他接口功能请求
前后端联调
思路
- 前端访问登录接口,登陆成功后,服务端会生成一个JWT令牌,并返回给前端,前端会将JWT令牌保存下来,在同一会话中共享JWT令牌信息,在访问其他功能接口时,前端会在请求头信息中存放JWT令牌信息,请求头的名称为token,过滤器Filter对请求实施统一拦截(登录请求不进行拦截,因为登录成功之后才会生成JWT令牌)并进行登录校验,如果JWT令牌存在并有效,Filter就会放行请求访问Web资源,否则返回错误信息。
登录校验Filter-流程
步骤
- 获取URL
- 判断请求中是否含有login,如果含有,说明是登录操作,放行
- 获取请求头中令牌(token)信息
- 判断令牌是否存在,如果不存在,返回错误结果(未登录)。
- 解析token,如果解析失败,返回错误结果(未登录)
- 放行
流程图
登录校验Filter-代码
过滤器类
-
package com.example.tlias.Filter; import com.alibaba.fastjson.JSONObject; import com.example.tlias.pojo.Result; import com.example.tlias.utils.JwtUtils; import jakarta.servlet.*; import jakarta.servlet.annotation.WebFilter; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.util.StringUtils; import java.io.IOException; @Slf4j @WebFilter(urlPatterns = "/*") public class LoginCheckFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; // 1.获取请求URL地址 String url = request.getRequestURI().toString(); log.info("获取到的URL地址为:{}", url); // 2.判断URL是否含有login路径,如果含有,则为登陆操作,放行 if (url.contains("login")) { log.info("此请求为登陆操作,放行......."); filterChain.doFilter(request, response); return; // todo 跳出过滤器 } // todo 以下是对于不是登录操作的过滤 // 3.获取请求头中的令牌(token) String token = request.getHeader("token"); // 4.判断是否存在,如果不存在,返回错误结果(未登录) if (!StringUtils.hasLength(token)) { log.info("请求头token为空,返回为登录的信息"); Result error = Result.error("NOT_LOGIN"); // 返回的错误信息通过接口文档与前端统一 // todo 手动转换 将对象-->json格式数据===》可以使用阿里巴巴fastJson的工具包,在pom.xml配置文件中添加相关依赖 // todo 控制类返回的对象会自动转换为JSON格式的字符串数据 String noLogin = JSONObject.toJSONString(error); // 将数据写入响应对象 response.getWriter().write(noLogin); return; // todo 跳出过滤器 } // 5.解析token,如果解析失败,返回错误结果(未登录) try { JwtUtils.parseJWT(token); // todo 如果解析失败方法就会报错 } catch (Exception e) { // token解析失败 e.printStackTrace(); log.info("解析令牌失败,返回未登录的错误信息"); Result error = Result.error("NOT_LOGIN"); String noLogin = JSONObject.toJSONString(error); response.getWriter().write(noLogin); return; } // 6.放行 log.info("令牌合法,放行"); filterChain.doFilter(request, response); } }
工具类
-
package com.example.tlias.utils; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import java.util.Date; import java.util.Map; public class JwtUtils { private static String signKey = "itheima"; // 设置签名密钥 private static Long expire = 43200000L; // 设置过期时间 /** * 生成JWT令牌 * * @param claims JWT第二部分负载 payload 中存储的内容 * @return */ public static String generateJwt(Map<String, Object> claims) { String jwt = Jwts.builder() .addClaims(claims) .signWith(SignatureAlgorithm.HS256, signKey) .setExpiration(new Date(System.currentTimeMillis() + expire)) .compact(); return jwt; } /** * 解析JWT令牌 * * @param jwt JWT令牌 * @return JWT第二部分负载 payload 中存储的内容 */ public static Claims parseJWT(String jwt) { Claims claims = Jwts.parser() .setSigningKey(signKey) .parseClaimsJws(jwt) .getBody(); return claims; } }
测试登录
- 使用postman发送请求
-
登录接口功能请求
- 登陆成功(返回登录成功信息及令牌信息)
-
登陆失败(返回登录失败信息)
- 登陆成功(返回登录成功信息及令牌信息)
-
其他接口功能请求
-
未登陆成功访问其他接口功能
-
-
- 登陆成功访问其他接口
-
-
前后端联调
Nginx项目压缩包地址如下:
https://hkm-web.oss-cn-beijing.aliyuncs.com/%E6%8E%A5%E5%8F%A3%E6%96%87%E6%A1%A3
运行及如果如下:
现在启动项目后会自动跳转到登陆界面,而不是和以前一样直接进入登陆后的界面
成功登录后就可以进入登陆后的界面