RestTemplate 发送请求时 Cookie 的影响及注意事项

背景

​ 一个基于 SpringCloud 的多服务项目中,服务间调用通过 Spring 的 RestTemplate 实现,后台模块 A 有一个定期清理无效业务数据的任务,它调用 Web 服务 B 的 API 时,竟然一直出现 Token 已过期问题。

技术背景:

Web 服务权限认证使用 Token ,登录校验成功后,刷新 Token 并调用 response.addCookie 返回给调用方——浏览器或者内部服务。
Web 服务的拦截器,它提取 Token 的顺序是:请求参数、Cookie、Header,然后验证 Token 的有效性。校验通过,刷新 Token 到响应对象的 Cookie 中。
Token 有效期限 30 分钟。
后台定时任务模块 A 每小时调用一次模块 B 的的 API 。
对于 Web 服务模块 B 来说,请求来源有用户浏览器和内部服务 A ,Token 校验通过后会刷新并设置响应对象的 Cookie 中,而 Cookie 又会在下次请求时发送给服务器。

各服务稳定运行后,定时任务 A 调用服务 B 的 API,从来都没有成功过。

后台服务调用时 Cookie 失效问题

问题描述:后台服务 A 在调用 B 的 某API 时,虽然会生成新 Token 信息并设置到头域,但是除了应用启动时成功调用了一次,其他周期的调用都出现了 Token 已过期问题。

问题分析:分析整个认证过程,发现在 Web 的拦截器中,如果检测到了内部服务调用,会刷新 Token 信息并返回给 RestTemplate 对象,而且拦截器提取 Token 的顺序是:请求参数、Cookie、Header。
问题症结

​ 后台模块 A 一小时执行一次,每次调用使用 Spring 托管的 RestTemplate 单例对象发送请求给 B 时,它包含了上次请求收到的 Cookie 信息。虽然同时生成了 Token 的头域信息,但是在 Web 端优先校验了 Cookie ,因此认证结果始终是无效 Token ,请求被拒绝。

解决:

在创建 RestTemplate 时,将构造好的参数填充到 RestTemplate 的属性中, 使用 disableCookieManagement 清楚 RestTemplate 中的 Cookie

import lombok.extern.slf4j.Slf4j;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;import javax.net.ssl.SSLContext;
/*** @author jiaohongtao*/
@Slf4j
public class RestTemplateUtil {public static HttpComponentsClientHttpRequestFactory generateHttpsRequestFactory() {try {TrustStrategy acceptingTrustStrategy = (x509Certificates, authType) -> true;SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();SSLConnectionSocketFactory connectionSocketFactory = new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier());HttpClientBuilder httpClientBuilder = HttpClients.custom();// 添加了ssl,没有的话可以不加// httpClientBuilder.setSSLSocketFactory(connectionSocketFactory);CloseableHttpClient httpClient = httpClientBuilder// 清除 RestTemplate 发送请求时的 Cookie,场景:多登录情况 cookie 不一致问题.disableCookieManagement()// 不支持重定向// .disableRedirectHandling().build();HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();factory.setHttpClient(httpClient);factory.setConnectTimeout(10 * 1000);factory.setReadTimeout(30 * 1000);return factory;} catch (Exception e) {throw new RuntimeException("创建HttpsRestTemplate失败", e);}}
}

使用时:可以看到 声明 RestTemplate时 使用了构造方法

private RestTemplate restTemplate = new RestTemplate(RestTemplateUtil.generateHttpsRequestFactory());

参考文献:
RestTemplate 发送请求时 Cookie 的影响及注意事项
在进行 HTTP 调用之前使用 RestTemplate 清除 Cookie(clear Cookies with RestTemplate before make HTTP-call)
RestTemplate 重定向问题 &cookie问题

RestTemplate 发送请求 清除Cookie相关推荐

  1. C# 发送带cookie的http请求_C#发送请求带cookie

    C# 发送带cookie的http请求_C#发送请求带cookie 一.Get请求带cookie 发送带cookie的请求,最好带上浏览器代理字符串: Mozilla/5.0 (Windows NT ...

  2. RestTemplate发送请求并携带header信息

    1.使用restTemplate的postForObject方法 注:目前没有发现发送携带header信息的getForObject方法. HttpHeaders headers = new Http ...

  3. ios html cookies,iOS-WKWebView携带cookie发送http请求,cookie失效

    发送请求代码: NSString *testUrl = @"http://10.22.122.7:8081/test2_action/view_index"; NSURL *url ...

  4. RestTemplate 发送http post请求

    RestTemplate : 传统情况下在java代码里访问restful服务,一般使用Apache的HttpClient.不过此种方法使用起来太过繁琐.spring提供了一种简单便捷的模板类来进行操 ...

  5. 爬虫之requests模块在headers参数中携带cookie发送请求

    爬虫之requests模块在headers参数中携带cookie发送请求 网站经常利用请求头中的Cookie字段来做用户访问状态的保持,那么我们可以在headers参数中添加Cookie,模拟普通用户 ...

  6. RestTemplate 发送 Https 请求调用

    RestTemplate 发送 Https 请求调用 个人博客:https://jacob.org.cn import org.apache.http.conn.ssl.NoopHostnameVer ...

  7. springboot 使用restTemplate 发送https请求 忽略ssl证书

    最近在写接口的时候给对方回推数据,发送https请求的时候遇到这么个报错:javax.net.ssl.SSLHandshakeException: sun.security.validator.Val ...

  8. restTemplate发送put请求

    restTemplate发送put请求 1.没有返回体 2.有返回体 HttpHeaders headers = new HttpHeaders(); headers.setContentType(o ...

  9. 【RestTemplate发送post、get请求】

    RestTemplate发送post.get请求 使用RestTemplate发送post请求 private String restTemplateByPost(String apiUrl, Map ...

最新文章

  1. Hadoop集群完全分布式模式环境部署
  2. recovery v1跟recovery v2的区别
  3. 下两个网段转发的路由设置_收藏 | 多台路由器,不同网段的设备之间如何互访?...
  4. 淘宝开发平台 java 调用实例
  5. Elasticsearch 之 数据索引
  6. 网站前端和后台性能优化22
  7. PHP error_reporting() 错误控制函数功能详解
  8. 分库分表中间件sharding-jdbc的使用
  9. python龙卷风框架_WEB框架之Tornado
  10. 交换机芯片技术知多少
  11. 基于帕累托最优的多目标SNP选择
  12. perl执行环境安装(Windows)
  13. 每日一诗词 —— 越人歌
  14. java中求两个数的最小公倍数,最大公约数的简便方法
  15. 3.云计算基础篇---云计算优势
  16. 无人驾驶出租车车队长沙惊艳亮相,BIE保驾护航
  17. Jmeter之参数化
  18. HTML链接CSS的三种方法
  19. 利用会声会影在局部,打马赛克
  20. 计算机机房电池后备时间规范,IDC机房UPS电池备用时间一般是多长时间?

热门文章

  1. 欧洲哲学发展趋势与中国哲学的机遇
  2. 修改servu数据库密码 servu加密方式
  3. 关于STC单片机的远程升级
  4. HSA人血清白蛋白修饰纳米金球金棒
  5. c语言什么是测试环境,vscode搭建与测试c语言运行环境
  6. FPGA中的LUT LUTRAM BRAM DSP FF
  7. 大数据学习内容及方法
  8. mysql的char在java中表示为_Java学习篇之-Mysql中varchar门类总结_mysql
  9. 上号神器,和平精英扫码登录教程
  10. IT项目管理个人作业05