万能搜索引擎网站,浙江省建设厅干部学校门户网站,西安到北京高铁多长时间,广告做图网站SpringBoot 微服务中怎么获取用户信息 token
当我们写了一个A接口#xff0c;这个接口需要调用B接口#xff0c;但是B接口需要包含请求头内容#xff0c;比如需要用户信息、用户id等内容#xff0c;由于不在同一个线程中#xff0c;使用ThreadLocal去获取数据是无法获取的…SpringBoot 微服务中怎么获取用户信息 token
当我们写了一个A接口这个接口需要调用B接口但是B接口需要包含请求头内容比如需要用户信息、用户id等内容由于不在同一个线程中使用ThreadLocal去获取数据是无法获取的这个时候需要手动将信息放置请求头中。
前置知识
获取请求头方式
return BaseContext.getUserId();是我随便写的不要在意
第一种 ServletRequestAttributes
通过ServletRequestAttributes获取请求。
GetMapping(/token)
public Long getToken() {ServletRequestAttributes requestAttributes (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();HttpServletRequest request requestAttributes.getRequest();String token request.getHeader(token);return BaseContext.getUserId();
}第二种 HttpServletRequest
GetMapping(/token)
public Long getToken(HttpServletRequest request) {String token request.getHeader(token);return BaseContext.getUserId();
}第二种 通过注解
GetMapping(/token)
public Long getToken(RequestHeader(token) String token) {return BaseContext.getUserId();
}操作步骤
准备好两个接口还有一个OpenFeign。
OpenFeign
FeignClient(value service-admin,contextId IndexFeignClient, path )
public interface IndexFeignClient {GetMapping(/token)Long getToken();
}被调用接口B
GetMapping(/token)
public Long getToken() {ServletRequestAttributes requestAttributes (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();HttpServletRequest request requestAttributes.getRequest();String token request.getHeader(token);return BaseContext.getUserId();
}调用接口A
GetMapping(abc)
public String index() {Long id indexFeignClient.getToken();return 欢迎访问。。。;
}这个时候正常去调用这个接口是无法获取到token相关信息的。 可以看到是null因为没有将请求头传递过来。 传递请求头
我使用的是JWT方式这种可以存储一些信息。使用的是注解方式存入请求头。
重写以实现对Feign请求的拦截和处理首先通过RequestContextHolder.getRequestAttributes()方法获取ServletRequestAttributes对象这个对象封装了当前请求的相关信息。然后将ServletRequestAttributes对象转换为ServletRequestAttributes类型并确保它不为空。
使用requestTemplate.header(token, token)方法将获取到的token值作为请求的header添加到Feign请求模板中。这样在发起Feign请求时会自动将token作为请求头一并发送给目标服务。
创建UserTokenFeignInterceptor
import feign.RequestInterceptor;
import feign.RequestTemplate;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;public class UserTokenFeignInterceptor implements RequestInterceptor {Overridepublic void apply(RequestTemplate requestTemplate) {ServletRequestAttributes requestAttributes (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();assert requestAttributes ! null;HttpServletRequest request requestAttributes.getRequest();String token request.getHeader(token);requestTemplate.header(token, token);}
}使用注解
使用Import将之前的UserTokenFeignInterceptor引入。
import cn.bunny.common.utils.feign.UserTokenFeignInterceptor;
import org.springframework.context.annotation.Import;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;Retention(value RetentionPolicy.RUNTIME)
Target(value ElementType.TYPE)
Import(value UserTokenFeignInterceptor.class)
public interface EnableUserTokenFeignInterceptor {}最后在接口启动类上加上这个注解也就是在接口A的启动类上这个注解。不要加错了
是接口A的启动类
是接口A的启动类
是接口A的启动类
EnableFeignClients(basePackages {cn.bunny.feign.admin})
SpringBootApplication
Slf4j
EnableUserTokenFeignInterceptor
public class ServiceWebApplication {public static void main(String[] args) {log.info(ServiceApplication启动...);SpringApplication.run(ServiceWebApplication.class, args);}
}之后就可以看到传递成功的token