【问题标题】:How do I parse multiple cookies from Set-Cookie header?如何从 Set-Cookie 标头解析多个 cookie?
【发布时间】:2022-01-31 23:48:50
【问题描述】:

我正在尝试从 Set-Cookie 标头中解析多个 cookie,我尝试在网络上寻找解决方案,但我很幸运。

这是我要解析的标头字符串。

blacklisted_tags=; path=/,,locale=en; path=/,,login=UserName; path=/; expires=Thu, 04-May-2017 22:35:39 GMT,,pass_hash=06xdbf50dfddb67f04352673g85o2645d7399xv; path=/; expires=Thu, 04-May-2017 22:35:39 GMT,_session=BAh7CDoMdXNlcl9pZGkDgGMBOg9hi4X9W9uX2lkIiVhNTBmOWYxMWZmYWY4ZjE4MTc3NWUxZjEyZWNmNzU3ZCIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNoSGFzaHsGOgtub3RpY2UiGllvdSBhcmUgbm93IGxvZ2dlZCBpbgY6Kn7j4MkewY7CEY%3D--18f67a3aa5cd039a23521dbf8d6be84e2ad55vnd; domain=.website.com; path=/; HttpOnly

这就是 fiddler 解析它的方式

Set-Cookie: blacklisted_tags=; path=/
Set-Cookie: 
Set-Cookie: locale=en; path=/
Set-Cookie: 
Set-Cookie: login=UserName; path=/; expires=Mon, 17-Apr-2017 17:34:43 GMT
Set-Cookie: 
Set-Cookie: pass_hash=06xdbf50dfddb67f04352673g85o2645d7399xv; path=/; expires=Mon, 17-Apr-2017 17:34:43 GMT
Set-Cookie: _session=BAh7CDoMdXNlcl9pZGkDgGMBOg9hi4X9W9uX2lkIiVhNTBmOWYxMWZmYWY4ZjE4MTc3NWUxZjEyZWNmNzU3ZCIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNoSGFzaHsGOgtub3RpY2UiGllvdSBhcmUgbm93IGxvZ2dlZCBpbgY6Kn7j4MkewY7CEY%3D--18f67a3aa5cd039a23521dbf8d6be84e2ad55vnd; domain=.website.com; path=/; HttpOnly

我已经尝试过这种 RegEx 模式,但它也不起作用

(.*?)=(.*?)($|;|,(?! ))

由于我对正则表达式不太擅长,我希望有人能帮助我使用正确的模式。

提前谢谢你。

【问题讨论】:

  • 能否请您告知带有这种 cookie 容器的 URL?
  • @WiktorStribiżew 我之前尝试过 CookieParser,但它没有帮助到 URL 我认为我不能在这里发布它,因为它是 NSFW,但是,你可以谷歌“Sankaku 频道”来获取它.我正在开发一个从该图像板下载图片的工具,我需要 cookie 以便我可以解析超过第 50 页(如果没有 cookie,您将获得 404!)。

标签: c# .net regex cookies


【解决方案1】:

如果您知道 uri - 只需使用 System.Net.CookieContainer。解析 cookie 可能容易出错,但 CookieContainer 可以为您完成。

【讨论】:

  • CookieContainer 只返回第一个(blacklisted_tags),我认为空值导致了这个问题(,,)
【解决方案2】:

别管我想通了!

我编写了这个小函数,它将响应中的 Set-Cookie 标头作为参数并返回给定 cookie 名称的值。

private string CookieValue(string header, string name)
{
    Match M = Regex.Match(header, string.Format("{0}=(?<value>.*?);", name));
    return (M.ToString().Split('=')[1]);
}

使用方法:

string passHash = CookieValue(Response.Headers[HttpResponseHeader.SetCookie], pass_hash);

如果您认为此功能有问题,请分享您的想法。

【讨论】:

  • 该值是否有可能包含;?如果是,这将失败。在运行正则表达式之前,您能否获得所有names 的列表?
  • @WiktorStribiżew 是的,该值将包含一个分号;,但您可以使用字符串删除/替换来删除第二个问题,检查我在上面发布的使用代码Response.Headers[HttpResponseHeader.SetCookie] 这将返回cookies来自响应中的 set-cookie 标头(检查我的问题中的第一个代码块),但请注意,它仅在有单个 set-cookie 标头时才有效。
  • 我的意思是问; 是否可以在值内,例如“name=part1;par2;part3;”你需要part1;par2;part3。您的正则表达式将仅提取 part1
  • @WiktorStribiżew 好吧,cookie 是用逗号分隔的 , 但是你可以在日期名称 expires=Mon, 17-Apr-2017 17:34:43 GMT 之后加上一个逗号,在这种情况下,你最终会得到 @ 987654332@ 作为无效的 cookie,正如我之前所说,我对 RegEx 不太擅长,所以对我来说唯一的解决方案是分别检索所有值并重建完整的 cookie。
  • 我会在我的孩子上床睡觉后分享我的正则表达式。
【解决方案3】:

cookies 用逗号分隔,但 Expires-date 也包含逗号。所以我使用这个(Java)代码:

public static final Pattern COOKIE_PATTERN = Pattern.compile("((?:[^,]|, )+)");

protected List<HttpCookie> parseCookieString(String setCookieHeaderValue)   {
    
    List<HttpCookie> parsed = new ArrayList<>();
    if (StringUtils.startsWith(setCookieHeaderValue, "[") && StringUtils.endsWith(setCookieHeaderValue, "]")) {

        List<String> stringList = parseCookieArray(removeFirstAndLastChar(setCookieHeaderValue));
        for (String string2 : stringList) {
            parsed.addAll(parseCookie(string2));
        }
    }
    else {
        parsed = parseCookie(setCookieHeaderValue);
    }
    return parsed;
}

private List<HttpCookie> parseCookie(String cookieString)
{
    try {
        return HttpCookie.parse(cookieString);
    }
    catch (IllegalArgumentException ex) {

        LOG.error("Recieved cookie could not be parsed. Skipping:" + cookieString);
        return Collections.emptyList();
    }

}

protected List<String> parseCookieArray(String string)
{
    List<String> cookieStrings = new ArrayList<>();
    String removeFirstAndLastChar = removeFirstAndLastChar(string);
    Matcher matcher = COOKIE_PATTERN.matcher(removeFirstAndLastChar);
    while (matcher.find()) {
        cookieStrings.add(matcher.group());
    }
    return cookieStrings;

}

protected String removeFirstAndLastChar(String string)
{
    return string.substring(1, string.length() - 1);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-04
    • 2016-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多