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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值