# 微服务之间调用免Token方案 ## 常见需求 1. 微服务版,定时任务中,通过openfeign调用其他服务,报错token失效 2. 微服务之间的feign调用,如何免登录,同时又不会被暴露网关 ## 解决方案 >[info] 通过以下三步就可以解决无TOEKN服务之间调用问题。 1. 模拟登录获取临时令牌TOKEN ``` /** * 获取临时令牌 * * 模拟登陆接口,获取模拟 Token * @return */ public static String getTemporaryToken() { RedisUtil redisUtil = SpringContextUtils.getBean(RedisUtil.class); //模拟登录生成临时Token //参数说明:第一个参数是用户名、第二个参数是密码的加密串 String token = JwtUtil.sign("??", "??"); // 设置Token缓存有效时间为 5 分钟 redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token); redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, 5 * 60 * 1000); return token; } ``` 2.在调用feign接口的前面加入下面代码 ``` //1.设置线程会话Token UserTokenContext.setToken(getTemporaryToken()); ``` 3. 所有的feign调用结束后,调用删除临时令牌方法 ``` //2.使用完删除Token,避免性能(这一步可以不做,但是为了性能建议执行) UserTokenContext.remove(); ``` > 示例代码截图: > ![](https://img.kancloud.cn/06/f2/06f23c372de1be7ae29bb48a375bca54_713x288.png) ## xxljob 完整代码 ``` package org.jeecg.modules.demo.xxljob; import com.xxl.job.core.biz.model.ReturnT; import com.xxl.job.core.handler.annotation.XxlJob; import lombok.extern.slf4j.Slf4j; import org.jeecg.common.config.mqtoken.UserTokenContext; import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.system.api.ISysBaseAPI; import org.jeecg.common.system.util.JwtUtil; import org.jeecg.common.util.RedisUtil; import org.jeecg.common.util.SpringContextUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** * xxl-job定时任务测试 */ @Component @Slf4j public class TestJobHandler { @Autowired ISysBaseAPI sysBaseApi; /** * 简单任务 * * @param params * @return */ @XxlJob(value = "testJob") public ReturnT<String> demoJobHandler(String params) { //1.设置线程会话Token UserTokenContext.setToken(getTemporaryToken()); log.info("我是 jeecg-demo 服务里的定时任务 testJob , 我执行了..............................."); log.info("我调用 jeecg-system 服务的字典接口:{}",sysBaseApi.queryAllDict()); //2.使用完删除Token,避免性能 UserTokenContext.remove(); return ReturnT.SUCCESS; } public void init() { log.info("init"); } public void destroy() { log.info("destory"); } /** * 获取临时令牌 * * 模拟登陆接口,获取模拟 Token * @return */ public static String getTemporaryToken() { RedisUtil redisUtil = SpringContextUtils.getBean(RedisUtil.class); // 模拟登录生成Token String token = JwtUtil.sign("??", "??"); // 设置Token缓存有效时间为 5 分钟 redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token); redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, 5 * 60 * 1000); return token; } } ``` ## 相关ISSUE * [https://gitee.com/jeecg/jeecg-boot/issues/I523YP](https://gitee.com/jeecg/jeecg-boot/issues/I523YP) * [https://gitee.com/jeecg/jeecg-boot/issues/I4Z69G](https://gitee.com/jeecg/jeecg-boot/issues/I4Z69G) * [https://github.com/jeecgboot/jeecg-boot/issues/2662](https://github.com/jeecgboot/jeecg-boot/issues/2662) * [https://gitee.com/jeecg/jeecg-boot/issues/I4Q7FY](https://gitee.com/jeecg/jeecg-boot/issues/I4Q7FY) * [https://github.com/jeecgboot/jeecg-boot/issues/2539](https://github.com/jeecgboot/jeecg-boot/issues/2539) * [https://github.com/jeecgboot/jeecg-boot/issues/2171](https://github.com/jeecgboot/jeecg-boot/issues/2171) * https://gitee.com/jeecg/jeecg-boot/issues/I4Q7FY ## 老版本手工修改 如果你的项目中没有相关类,可以拷贝jeecgboot最新版代码到自己项目中。 - 主要改动文件: ``` jeecg-boot-base/jeecg-boot-base-tools/org.jeecg.common.config.mqtoken.UserTokenContext jeecg-boot-starter\jeecg-boot-starter-cloud\src\main\java\org\jeecg\config\FeignConfig.java jeecg-boot-base\jeecg-boot-base-api\jeecg-system-cloud-api\src\main\java\org\jeecg\config\FeignConfig.java ```