SpringBoot中使用Feign调用第三方接口时动态获取Token添加到请求头中
需求:调用第三方接口时需要使用第三方提供的账号密码获取到ToKen,在调用除登陆接口之外的接口都需要把token放入请求header当中。说明:我把登录接口都放到了一个client类中,便于后期维护,对不需要加载Token的方法,我们添加一个header标识一下(如下图用户登录接口上@PostMappeing上的headers = {"No-Need-ToToken=true"})参数,在执行ap
·
需求:调用第三方接口时需要使用第三方提供的账号密码获取到ToKen,在调用除登陆接口之外的接口都需要把token放入请求header当中。
说明:我把登录接口都放到了一个client类中,便于后期维护,对不需要加载Token的方法,我们添加一个header标识一下(如下图用户登录接口上@PostMappeing上的headers = {"No-Need-ToToken=true"})参数,在执行apply方法时直接跳过加载token
1.实现feign提供的RequestInterceptor接口重写apply方法(注入JuRuiClient需要使用@Lazy注解,不然调用时会出现循环调用的问题)
package cn.victorplus.cas.gps.config;
import cn.victorplus.cas.gps.client.jurui.JuRuiClient;
import cn.victorplus.cas.gps.client.jurui.dto.JuRuiRespDto;
import cn.victorplus.cas.gps.client.jurui.enums.JuRuiCodeEnum;
import cn.victorplus.cas.gps.client.jurui.enums.LoginReturnCodeEnum;
import cn.victorplus.cas.gps.config.propeties.JuRuiProperties;
import cn.victorplus.cas.gps.exception.BaseException;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.HashMap;
import java.util.Map;
/**
* 聚瑞云控接口调用拦截器
* @author penglianghu
* @date 2022/1/20/0020 10:44
*/
@Slf4j
@Configuration
public class JuRuiClientConfig implements RequestInterceptor {
/**
* 聚瑞云控厂商规定token请求头名称
*/
public static final String AUTHORIZATION = "Authorization";
/**
* 不需要token请求头标识
*/
public static final String NO_NEED_TO_TOKEN = "No-Need-To-Token";
@Autowired
private JuRuiProperties juRuiProperties;
@Autowired
@Lazy
private JuRuiClient juRuiClient;
@Override
public void apply(RequestTemplate requestTemplate) {
//获取接口是否不需要加载token
boolean noNeedToToken = requestTemplate.headers().containsKey(NO_NEED_TO_TOKEN);
//取反就是需要加载token
if (!noNeedToToken) {
//获取用户认证token
String token = this.getToken();
//把用户认证token添加到请求头中
requestTemplate.header(AUTHORIZATION, token);
}
}
/**
* 使用系统配置默认用户获取token
*
* @return token 用户登录凭证
*/
public String getToken() {
//使用系统配置的用户名密码进行登录
return this.getToken(juRuiProperties.getLoginName(), juRuiProperties.getPassword());
}
/**
* 使用自定义用户获取token 获取成功存入缓存中
*
* @param loginName 用户名
* @param passWord 密码
* @return token 用户登录凭证
*/
@Cacheable(cacheNames = RedisConfig.JU_RUI_TOKEN, key = "'loginName:'+#loginName")
public String getToken(String loginName, String passWord) {
log.debug(String.format("【聚瑞云控】开始获取用户token,用户名:%s", loginName));
//开始构建请求参数
Map<String, Object> params = new HashMap<>(2);
//设置用户名
params.put("loginName", loginName);
//设置密码
params.put("passWord", passWord);
//调用聚瑞云控接口获取用户token
JuRuiRespDto<String> loginTokenRespDto = juRuiClient.getLoginToken(params);
//异常处理
if (JuRuiCodeEnum.isError(loginTokenRespDto.getCode())) {
String errorMsg = loginTokenRespDto.getMsg();
if (StringUtils.isBlank(errorMsg)) {
errorMsg = LoginReturnCodeEnum.getCodeMsg(loginTokenRespDto.getCode());
}
log.error("【聚瑞云控】获取用户token失败,用户名:{},失败原因:{}", loginName, errorMsg);
throw new BaseException(String.format("【聚瑞云控】获取用户token失败,用户名:%s,失败原因:%s", loginName, errorMsg));
}
log.debug(String.format("【聚瑞云控】获取用户token成功,用户名:%s", loginName));
return loginTokenRespDto.getData();
}
}
2.FeignClient类,@FeignClient中的configuration指定为步骤1我们实现的类
有更好的思路欢迎评论区留言
更多推荐
已为社区贡献1条内容
所有评论(0)