当前位置: 首页 > article >正文

SpringCloud系列教程(十):token验证

上一节完成了gateway和微服务之间的token传递和验证,并且能正常获取到gateway解析出来的用户信息,看上去已经完成了,但是呢,如果我们微服务越来越多呢?难道每一个微服务都要添加一套解析功能吗?这样既浪费开发人员的时间,又无法保证所有人都能完成统一的验证功能,很可能最后变得项目验证方式五花八门,所以我们把token验证提取出来,单独作为一个项目,任何服务只要引入这个项目就能自动完成token验证的工作。

1、单独创建一个项目common,这个项目基本不怎么加SpringCloud的依赖,主要靠我们去写代码。

2、把之前写的TokenTool和JwtConfig两个文件复制到common项目里。

3、创建一个UserTool,用来保存userId信息,后续如果有其他的信息就可以继续丰富这个类了。

package com.mj.common.tool;

public class UserTool {
    private static final ThreadLocal<String> tl = new ThreadLocal<>();

    public static void addUserId(String userId) {
        tl.set(userId);
    }

    public static String getUserId() {
        return tl.get();
    }

    public static void removeUserId() {
        tl.remove();
    }
}

4、创建一个拦截器UserInterceptor,它的功能其实不是拦截,而是拦截之后取出userId,然后继续执行请求,并没有真正拦截的逻辑。

package com.mj.common.interceptor;

import cn.hutool.core.util.StrUtil;
import com.mj.common.tool.UserTool;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;

public class UserInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String userid = request.getHeader("userid");
        if (StrUtil.isNotBlank(userid)) {
            UserTool.addUserId(userid);
        }
        //全部放行,只是加了userId,并不执行拦截任务
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        UserTool.removeUserId();
    }
}

我们真正的逻辑其实是把userId存起来,当请求完成时再把userId释放掉,每次请求都是一个独立线程,所以我们使用ThreadLocal来保存不同线程间的数据。

5、只有拦截器没什么用,因为这时候无法正常拦截请求,我们要把拦截器加入到服务中才行,所以我们再创建一个InterceptorConfig,把拦截器加进去。

package com.mj.common.config;

import com.mj.common.interceptor.UserInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new UserInterceptor());
    }
}

6、这样任何需要用common的module只要把它当做依赖引入项目里就可以了,我们把跟common重复的那些类文件删掉,这里注意,我们在nacos-client-demo项目里使用的JwtConfig文件本来是自动注入的,但是由于提取到了common中,就不会自动注入了,所以我们在nacos-client-demo的启动类上添加扫描的包名,从而把common中的也扫进去,gateway-demo不需要加,因为它不需要,所以common中的拦截器和config就被自动忽略。

package com.mj.nacosclient;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication(scanBasePackages = "com.mj")
public class NacosClientDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(NacosClientDemoApplication.class, args);
    }
}

7、这样项目就变成了这样一个清爽的样子。

8、重启服务,再测试一下吧,效果和上一节的一样,由于我们是对项目重构了,所以同学们要仔细修改。


http://www.kler.cn/a/568432.html

相关文章:

  • Hadoop之01:HDFS分布式文件系统
  • 纳米材料简介
  • 【VitePress】vitepress 中 markdown 写作使用
  • Hadoop之02:MR-图解
  • 基于Flask实现的多语言Hello World
  • 企业如何将ERP和BPM项目结合提升核心竞争力
  • 【数据挖掘】Matplotlib
  • Kubespray部署企业级高可用K8S指南
  • 基于Python Django的人脸识别上课考勤系统(附源码,部署)
  • uniapp 系统学习,从入门到实战(七)—— 网络请求与数据交互
  • 《国密算法开发实战:从合规落地到性能优化》
  • springboot项目Maven打包遇到的问题总结
  • 使用 REINFORCE 算法强化梯度策略
  • Android Studio安装与配置详解
  • 为你详细介绍系统数据库的概念结构、逻辑结构、物理结构设计方法,以及数据库的物理独立性的相关内容:
  • 正向代理、反向代理
  • 网络安全与等保2.0
  • 【Java项目】基于Spring Boot的体质测试数据分析及可视化设计
  • 力扣2662. 前往目标的最小代价
  • DeepSeek掘金——DeepSeek R1驱动的PDF机器人