springboot登录校验[JWT]

前言
作者简介:我是笑霸final,一名热爱技术的在校学生。
个人主页:个人主页1 || 笑霸final的主页2
系列专栏:后端专栏
如果文章知识点有错误的地方,请指正!和大家一起学习,一起进步
如果感觉博主的文章还不错的话,点赞 + 关注 + 收藏

在这里插入图片描述

目录

  • 一、初识登录校验
  • 二、Jwt令牌
  • 三、JWT的生成
  • 四、统一校验【filter过滤器方式】
  • 五、统一校验【interceputer拦截器器方式】
  • 题外篇【springboot新手开发起步】

一、初识登录校验

啥是登录校验?

  • 所谓登录校验,指的是我们在服务器端接收到浏览器发送过来的请求之后,首先我们要对请求进行校验。先要校验一下用户登录了没有,如果用户已经登录了,就直接执行对应的业务操作就可以了;如果用户没有登录,此时就不允许他执行相关的业务操作,直接给前端响应一个错误的结果,最终跳转到登录页面,要求他登录成功之后,再来访问对应的数据

常见的登录校验

springboot登录校验[JWT]_第1张图片

分布式之session共享问题 4种解决方案及spring session的使用
这里推荐 做时间的朋友。的一篇文章点此跳转
https://blog.csdn.net/weixin_44335140/article/details/112994824

二、Jwt令牌

  • 全称:JSON Web Token (https:/ /jwt.io/ )
  • 定义了一种简洁的、自包含的格式,用于在通信双方以json数据格式安全的传输信息。由于数字签名的存在,这些信息是可靠的。

组成
在这里插入图片描述

  • 第一部分:Header(头),记录令牌类型、签名算法等。例如:{“alg”:“HS256”, “type” :“JIWT”)
  • 第二部分: Payload(有效载荷),携带一些自定义信息、默认信息等。例如:{“id”.“1”,“username”:“Tom”}
  • 第三部分: Signature(签名),防止Token被篡改、确保安全性。将header、payload,并加入指定秘钥,通过指定签名算法计算而来。
    在这里插入图片描述

JWT的登录场景
springboot登录校验[JWT]_第2张图片
右上面可知我们就需要实现生成jwt令牌和实现一个统一拦截 校验

三、JWT的生成

一、引入依赖



        <dependency>
            <groupId>io.jsonwebtokengroupId>
            <artifactId>jjwtartifactId>
            <version>0.9.0version>
        dependency>

然后就能使用提供的 Jwts工具类了


二、生成JWT

  • signWith()签名算法和密钥
  • setClaims()存储自定义的数据(载荷)
  • setExpiration()有效期
 String JWTString = Jwts.builder()//生成jwt令牌
                .signWith(SignatureAlgorithm.HS256, "xbfinal")// 签名算法和密钥
                .setClaims(hashMap)//存储自定义的数据(载荷)
                //System.currentTimeMillis()获取当前时间毫秒值 一下表示当前时间后的一个小时
                .setExpiration(new Date(System.currentTimeMillis() + 3600 * 1000))//有效期  1小时
                .compact();
        System.out.println(JWTString);

在这里插入图片描述
三、JWT令牌的解析

  • setSigningKey() 签名密钥
  • parseClaimsJws()传入生成的 jwt令牌
  • getBody()拿到我们自定义的内容
 Claims keyBody = Jwts.parser()
                .setSigningKey("xbfinal")//签名密钥
                //传入生成的 jwt令牌
                .parseClaimsJws("eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoi56yR6Zy4ZmluYWwiLCJleHAiOjE2ODEzNTQxMTcsImFnZSI6IjE4In0.77CDL0t1yFGDeXvM9pH5TKT1Pt5Xq6rUdycl4yPCC6Q")
                .getBody();//拿到我们自定义的内容

        Map<String, Object> stringObjectMap = BeanUtil.beanToMap(keyBody);
        System.out.println(stringObjectMap.get("name"));
        System.out.println(keyBody);

springboot登录校验[JWT]_第3张图片

四、统一校验【filter过滤器方式】

@Slf4j
@WebFilter(urlPatterns = "/*")  //别忘了   启动类加上@ServletComponentScan注解
public class LoginCheckFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        //获取请求url
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse res = (HttpServletResponse) servletResponse;

        String requestURL = req.getRequestURL().toString();
        log.info("请求地址{}",requestURL);

        //判断是不是登录请求?是的话就放行
        if(requestURL.contains("doLogin")){
            log.info("登录放行");
            filterChain.doFilter(servletRequest,servletResponse);
            return;//返回的时候直接返回 不执行下面的代码
        }

        //获取请求头中的token
        String jwt = req.getHeader("JWTStr");
        //验证令牌
        if(StrUtil.isEmpty(jwt)){
            //不存在
            log.info("token为空");

            String jsonStr = JSONUtil.toJsonStr(SaResult.error("没有登录").toString());
            res.getWriter().write(jsonStr);
            return;
        }
        try{
            Claims parser = MyJwtUtils.parser(jwt);

        }catch (Exception e){
            log.info("token为空");
              String jsonStr = JSONUtil.toJsonStr(SaResult.error("没有登录").toString());
            response.getWriter().write(jsonStr);
            return;
        }

        //放行
        filterChain.doFilter(servletRequest,servletResponse);



    }
}

注意 :需要前端把jwt放入请求头中

五、统一校验【interceputer拦截器器方式】

  • 先编写拦截器类并实现HandlerInterceptor 接口
  • 注册拦截器WebMvcConfigurer
@Slf4j
@Component //拦截器配置好后别忘了注册
public class LoginCheckInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        //获取请求头中的token
        String jwt = request.getHeader("satoken");
        //验证令牌
        if(StrUtil.isEmpty(jwt)){
            //不存在
            log.info("token为空");
            String jsonStr = JSONUtil.toJsonStr(SaResult.error("没有登录").toString());
            response.getWriter().write(jsonStr);
            return false;
        }
        try{

            Claims parser = MyJwtUtils.parser(jwt);

        }catch (Exception e){
            log.info("token为空");
            String jsonStr = JSONUtil.toJsonStr(SaResult.error("没有登录").toString());
            response.getWriter().write(jsonStr);
            return false;
        }

        //放行
        log.info("登录放行");
        return true;
    }

注册拦截器

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    LoginCheckInterceptor loginCheckInterceptor;

    /**
     * 注册拦截器的方法
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginCheckInterceptor)
                .addPathPatterns("/**")//拦截所以资源
                .excludePathPatterns("/user/doLogin/**")//排除路径
//                .order(1) 有多个拦截器的话设置优先级 数字越小优先级越高
        ;
        
    }
}

注意 :需要前端把jwt放入请求头中

题外篇【springboot新手开发起步】

springboot登录校验[JWT]_第4张图片
链接我的另一篇博客

你可能感兴趣的:(后端,spring,boot,java,前端)