An invalid domain [xx] was specified for this cookie

背景

spring boot项目将jetty改成tomcat后,登录接口报错–登录接口有addCookie的逻辑
An invalid domain [xxxx] was specified for this cookie
全局搜索代码后,发现该提示来自tomcat-/tomcat-embed-core/9.0.46/tomcat-embed-core-9.0.46-sources.jar!/org/apache/tomcat/util/http/LocalStrings.properties。
进一步找到引用该提示语的地方为org.apache.tomcat.util.http.Rfc6265CookieProcessor

    ## 应用层addCookie的时候会走到这个方法
    @Override
    public String generateHeader(javax.servlet.http.Cookie cookie, HttpServletRequest request) {
        StringBuffer header = new StringBuffer();
        header.append(cookie.getName());
        header.append('=');
        String value = cookie.getValue();
        if (value != null && value.length() > 0) {
            validateCookieValue(value);
            header.append(value);
        }
        ... ...
        String domain = cookie.getDomain();
        if (domain != null && domain.length() > 0) {
            # 校验cookie的domian属性
            validateDomain(domain);
            header.append("; Domain=");
            header.append(domain);
        }
        ... ...
        return header.toString();
    }
    private static final BitSet domainValid = new BitSet(128);

    static {
        for (char c = '0'; c <= '9'; c++) {
            domainValid.set(c);
        }
        for (char c = 'a'; c <= 'z'; c++) {
            domainValid.set(c);
        }
        for (char c = 'A'; c <= 'Z'; c++) {
            domainValid.set(c);
        }
        domainValid.set('.');
        domainValid.set('-');
    }
    private void validateDomain(String domain) {
        int i = 0;
        int prev = -1;
        int cur = -1;
        char[] chars = domain.toCharArray();
        while (i < chars.length) {
            prev = cur;
            cur = chars[i];
            # cookie的domain属性值只能包含字母、数字、“-”、“.if (!domainValid.get(cur)) {
                throw new IllegalArgumentException(sm.getString(
                        "rfc6265CookieProcessor.invalidDomain", domain));
            }
            # cookie的domain属性值第一个字母不能为“.if ((prev == '.' || prev == -1) && (cur == '.' || cur == '-')) {
                throw new IllegalArgumentException(sm.getString(
                        "rfc6265CookieProcessor.invalidDomain", domain));
            }
            # cookie的domain属性值最后一个字母不能为“.if (prev == '-' && cur == '.') {
                throw new IllegalArgumentException(sm.getString(
                        "rfc6265CookieProcessor.invalidDomain", domain));
            }
            i++;
        }
        ... ...
    }

解决方案

解决方案1-domian不以"."开头

以前cookie domain属性中开头的".",代表该cookie对子域名也是有效的。比如domain设成“.example.com”;
"www.example.com”、“www.corp.example.com”、"example.com"浏览器访问这三个网址的时候,都能将cookie自动带到服务端。
RFC 6265规范出来后,上述规则被修改了;浏览器会忽略domain属性中前缀“.”,而且自动对子域名生效。

上述内容可以参考https://stackoverflow.com/questions/9618217/what-does-the-dot-prefix-in-the-cookie-domain-mean。以及RFC 6265的官方说明。

The Domain attribute specifies those hosts to which the cookie will
be sent. For example, if the value of the Domain attribute is
“example.com”, the user agent will include the cookie in the Cookie
header when making HTTP requests to example.com, www.example.com, and
www.corp.example.com. (Note that a leading %x2E (“.”), if present,
is ignored even though that character is not permitted
, but a
trailing %x2E (“.”), if present, will cause the user agent to ignore
the attribute.) If the server omits the Domain attribute, the user
agent will return the cookie only to the origin server.

解决方案2-替换tomcat默认的cookie处理器

legacy代表遗产、遗留的意思;LegacyCookieProcessor就表示对老的cookie的标准做的兼容。看源码可以发现LegacyCookieProcessor不会对domain的属性进行校验。

 @Bean
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> cookieProcessorCustomizer() {
	return (factory) -> factory.addContextCustomizers(
			(context) -> context.setCookieProcessor(new LegacyCookieProcessor()));
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值