RestTemplate 发送请求 清除Cookie
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相关推荐
- C# 发送带cookie的http请求_C#发送请求带cookie
C# 发送带cookie的http请求_C#发送请求带cookie 一.Get请求带cookie 发送带cookie的请求,最好带上浏览器代理字符串: Mozilla/5.0 (Windows NT ...
- RestTemplate发送请求并携带header信息
1.使用restTemplate的postForObject方法 注:目前没有发现发送携带header信息的getForObject方法. HttpHeaders headers = new Http ...
- ios html cookies,iOS-WKWebView携带cookie发送http请求,cookie失效
发送请求代码: NSString *testUrl = @"http://10.22.122.7:8081/test2_action/view_index"; NSURL *url ...
- RestTemplate 发送http post请求
RestTemplate : 传统情况下在java代码里访问restful服务,一般使用Apache的HttpClient.不过此种方法使用起来太过繁琐.spring提供了一种简单便捷的模板类来进行操 ...
- 爬虫之requests模块在headers参数中携带cookie发送请求
爬虫之requests模块在headers参数中携带cookie发送请求 网站经常利用请求头中的Cookie字段来做用户访问状态的保持,那么我们可以在headers参数中添加Cookie,模拟普通用户 ...
- RestTemplate 发送 Https 请求调用
RestTemplate 发送 Https 请求调用 个人博客:https://jacob.org.cn import org.apache.http.conn.ssl.NoopHostnameVer ...
- springboot 使用restTemplate 发送https请求 忽略ssl证书
最近在写接口的时候给对方回推数据,发送https请求的时候遇到这么个报错:javax.net.ssl.SSLHandshakeException: sun.security.validator.Val ...
- restTemplate发送put请求
restTemplate发送put请求 1.没有返回体 2.有返回体 HttpHeaders headers = new HttpHeaders(); headers.setContentType(o ...
- 【RestTemplate发送post、get请求】
RestTemplate发送post.get请求 使用RestTemplate发送post请求 private String restTemplateByPost(String apiUrl, Map ...
最新文章
- Hadoop集群完全分布式模式环境部署
- recovery v1跟recovery v2的区别
- 下两个网段转发的路由设置_收藏 | 多台路由器,不同网段的设备之间如何互访?...
- 淘宝开发平台 java 调用实例
- Elasticsearch 之 数据索引
- 网站前端和后台性能优化22
- PHP error_reporting() 错误控制函数功能详解
- 分库分表中间件sharding-jdbc的使用
- python龙卷风框架_WEB框架之Tornado
- 交换机芯片技术知多少
- 基于帕累托最优的多目标SNP选择
- perl执行环境安装(Windows)
- 每日一诗词 —— 越人歌
- java中求两个数的最小公倍数,最大公约数的简便方法
- 3.云计算基础篇---云计算优势
- 无人驾驶出租车车队长沙惊艳亮相,BIE保驾护航
- Jmeter之参数化
- HTML链接CSS的三种方法
- 利用会声会影在局部,打马赛克
- 计算机机房电池后备时间规范,IDC机房UPS电池备用时间一般是多长时间?