关于Cookie中不过滤“=”号的方法

本文详细介绍了在使用Tomcat时遇到的Cookie截断问题,特别是当Cookie值包含特殊字符如=时,如何通过修改catalina.properties文件中的设置来解决此问题,确保能够完整获取Cookie值。
当用cookie.getValue()方法获取Cookie的值时,结果遇到"="号时就会自动截断,后面的值就取不到了。这是因为tomcat中的Cookie信息默认是不允许有特殊字符的,所以有特殊字符时就会取不到。这时你可以在tomcat中的conf文件夹下的catalina.properties文件中添加如下代码:
org.apache.tomcat.util.http.ServerCookie.ALLOW_EQUALS_IN_VALUE=true
当添加这段代码后,你会发现你用cookie.getValue()就可以取到包含"="的cookie的值了。


----------------------------------------------------------------------

Tomcat truncating cookies with = values

Starting with Tomcat 6.0.18 and in Tomcat 7.x any cookie containing a “=” will be truncated. Where you would expect your cookie to hold all values, e.g. “value1=myname&value2=password” you will only be able to retrieve the “value1=”.

This is because Tomcat now adheres to the cookie spec more tightly than previous versions. If you are in control of the cookie you might be able to change it and work around this. If not, then you can can change the settings within the catalina.properties file by appending the following two settings:

org.apache.tomcat.util.http.ServerCookie.ALLOW_EQUALS_IN_VALUE=true
org.apache.tomcat.util.http.ServerCookie.ALLOW_HTTP_SEPARATORS_IN_V0=true
<think>好的,我现在要解决用户关于OkHttp3中Cookie的Domain属性以及如何设置宽松策略的问题。首先,我需要回顾之前提供的引用内容,确保回答准确。 用户的问题主要分为两部分:set-cookie中的Domain属性作用及其是否会导致cookie过滤,以及在OkHttpClient中如何设置宽松的Cookie策略。根据之前的引用,特别是引用[3]和引用[4],用户可能在使用OkHttp3时遇到了Cookie因Domain匹配而被过滤的情况,想要了解原因和解决方法。 首先,Domain属性的作用。根据HTTP标准,Domain属性指定了哪些主机可以接收Cookie。如果未指定,默认是当前主机,包含子域名。例如,如果Domain设置为qqqq.com,那么Cookie会被发送到qqqq.com及其子域名如a.qqqq.com。但OkHttp3在处理Cookie时会严格检查Domain是否匹配请求的URL,如果匹配,Cookie会被过滤。这可能导致用户遇到Cookie未被正确发送的问题。 接下来,用户想知道如何设置宽松策略。根据之前的回答,OkHttp3通过CookieJar接口管理Cookie,没有直接暴露CookiePolicy,但可以通过自定义CookieJar来实现宽松策略。引用[1]提到使用CookieManager和CookiePolicy.ACCEPT_ALL,但这是针对OkHttp旧版本的,OkHttp3需要使用同的方法。 用户提供的引用中提到,可以通过自定义CookieStore和CookieManager来持久化Cookie,并设置CookiePolicy。但OkHttp3使用CookieJar,因此需要实现自定义的CookieJar,覆盖saveFromResponse和loadForRequest方法,在loadForRequest时绕过Domain验证。例如,在loadForRequest中强制设置Cookie的Domain为当前请求的host,或者忽略Domain检查,直接返回所有存储的Cookie。 此外,引用[4]指出,Cookie默认绑定到特定host,跨域需要手动处理。用户可能需要允许跨域发送Cookie,因此需要在自定义CookieJar中处理Domain属性,使其匹配同的host。 需要注意的安全问题,宽松策略可能导致安全风险,如CSRF攻击或Cookie泄露,但用户可能只是在测试环境中需要临时解决方案。因此,在回答中需要提到这些风险,并建议生产环境中使用严格策略。 最后,根据用户提供的代码示例,可能需要展示如何实现自定义CookieJar,覆盖Domain验证,并允许跨域发送Cookie。同时,验证方法部分需要指导用户如何测试Cookie是否被正确发送,例如通过日志检查请求头中的Cookie信息。 总结步骤:解释Domain属性的作用,说明OkHttp3默认的严格策略导致Cookie过滤,展示如何通过自定义CookieJar实现宽松策略,包括修改Domain和Secure标志,最后提醒安全风险和测试方法。</think>--- ### 一、`Domain`属性的核心作用与过滤机制 1. **HTTP协议规范定义** `Domain`属性用于指定Cookie生效的域名范围,格式要求为: - 必须包含前置点(如`.qqqq.com`表示所有子域名) - 未显式设置时默认绑定请求的host(如`api.qqqq.com`的Cookie仅在该host生效)[^1] 2. **OkHttp3的严格校验规则** ```java // OkHttp源码中的Domain匹配验证逻辑 public boolean matches(HttpUrl url) { // 校验请求host是否与Cookie.domain匹配(区分大小写) return HttpUrl.domainMatch(cookie.domain, url.host()); } ``` - **过滤场景**:当请求的host满足`Domain`范围时,Cookie会被自动丢弃[^2] - **示例**:Cookie的Domain为`.qqqq.com`时,`a.qqqq.com`可携带,但`qqqq.org`会被过滤 --- ### 二、OkHttp3中实现宽松策略的实践方案 #### 步骤1:创建自定义`CookieJar` ```kotlin class LenientCookieJar : CookieJar { private val cookieStore = mutableMapOf<String, List<Cookie>>() override fun saveFromResponse(url: HttpUrl, cookies: List<Cookie>) { // 强制保存所有Cookie(无论Domain是否匹配) cookieStore[url.host] = cookies.map { it.newBuilder().domain(url.host).build() // 覆盖原始Domain为当前host } } override fun loadForRequest(url: HttpUrl): List<Cookie> { // 返回所有存储的Cookie(忽略Domain验证) return cookieStore.values.flatten().map { it.newBuilder().domain(url.host).build() // 动态修改Domain匹配当前请求 } } } ``` #### 步骤2:配置OkHttpClient ```kotlin val okHttpClient = OkHttpClient.Builder() .cookieJar(LenientCookieJar()) .build() ``` #### 关键参数控制表 | 限制类型 | 宽松策略实现方式 | 风险说明 | |----------------|------------------------------------|--------------------------| | Domain匹配 | 动态覆盖Cookie.domain为请求host | 可能导致跨域安全问题[^3] | | Path匹配 | 返回所有Path的Cookie | 资源访问越权风险 | | Secure标记 | 修改Cookie.secure=false | HTTP传输中暴露敏感数据[^4]| --- ### 三、Domain属性过滤问题的验证方法 1. **跨子域名测试** ```kotlin // 向同子域名发送请求 val request1 = Request.Builder().url("https://api.qqqq.com/login").build() val request2 = Request.Builder().url("https://shop.qqqq.com/data").build() okHttpClient.newCall(request1).execute().close() // 保存Cookie okHttpClient.newCall(request2).execute().use { println("携带Cookie: ${it.request.headers["Cookie"]}") } ``` 2. **Domain格式验证** ```kotlin // 观察Cookie的Domain值变化 cookieJar.cookieStore.forEach { (host, cookies) -> cookies.forEach { println("存储Cookie: ${it.name} 原始Domain=${it.domain} 修改后Domain=$host") } } ``` --- ### 四、生产环境注意事项 1. **安全加固建议** ```gradle // 使用安全库进行Cookie加密 implementation "androidx.security:security-crypto:1.1.0-alpha06" ``` 2. **动态策略切换** ```kotlin // 根据BuildConfig区分环境 if (BuildConfig.DEBUG) { client.cookieJar = LenientCookieJar() } else { client.cookieJar = PersistentCookieJar() } ``` --- ### 五、高级场景解决方案 1. **强制跨域共享Cookie** ```kotlin // 在Interceptor中手动添加Cookie okHttpClient.addInterceptor { chain -> val request = chain.request() .newBuilder() .header("Cookie", "session_id=xxxx; domain=qqqq.com") .build() chain.proceed(request) } ``` 2. **Domain通配符处理** ```kotlin // 修改Domain为通配格式 fun Cookie.toWildcardDomain(): Cookie { return this.newBuilder() .domain(if (!domain.startsWith(".")) ".$domain" else domain) .build() } ``` --- [^1]: RFC 6265规定Domain属性必须以点开头实现子域名覆盖 : OkHttp3源码中Cookie的匹配算法区分精确域名和通配域名 [^3]: OWASP建议严格限制跨域Cookie以防止CSRF攻击 [^4]: Android 9及以上强制要求HTTPS通信时Secure标记为true
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值