【问题标题】:Retrieve ALL cookies from Internet Explorer从 Internet Explorer 检索所有 cookie
【发布时间】:2016-12-08 03:51:29
【问题描述】:

我正在尝试检索与我打开的特定页面相关联的所有 cookie(我已经过身份验证)。有几个与网页相关的 cookie,我需要检索每个 cookie 以便稍后进行 POST。

我尝试了几种方法,但都没有给我完整的列表。到目前为止,我已经在 VBA 中编写了代码,但我也可以在 .NET 中使用它。

第一次尝试,在获得指向 IE 的指针之后。

arraycookie = Split(ie.document.Cookie, ";")

For i = LBound(arraycookie) To UBound(arraycookie)
    Debug.Print arraycookie(i)
Next i

这给了我一些 cookie,但不是全部。我可以在开发人员工具 (F12) 中查看 cookie,并确认没有 cookie 标记了仅 HTTP 标志。见下图。

我还尝试了 InternetGetCookie windows API。它返回一个 cookie,但只有一个,无论名称是什么,它都是同一个(例如下面的 FedAuth)。

Private Sub GetCookieAttempt()
Dim sCookieVal As String * 256
Dim bRet As Boolean
bRet = InternetGetCookie("https://mywebsiteaddresshere.com", _
    "FedAuth", sCookieVal, 255)
    If bRet = False Then
        MsgBox "Failed"
    Else
        MsgBox sCookieVal
    End If
End Sub

这只是一个猜测(知道我是怎么知道的吗?),但从我读到的内容可能是 cookie 受到保护。我查看了 IEGetProtectedModeCookie API,但无法让它返回 cookie 信息。

不知道为什么我可以通过开发人员工具看到这一点,但是当我尝试公开信息时,它并没有返回所有内容。

任何帮助将不胜感激:)

谢谢!


编辑

因此,在研究了这个问题之后,我想我会尝试使用不同的浏览器尝试相同的网页,然后再次查看 cookie 详细信息。

使用 Firebug,我试图检索的 cookie 现在显示一个 HTTPOnly 标志。据我了解,我可以使用 InternetGetCookieEx 并指定 INTERNET_COOKIE_HTTPONLY 标志。但是我无法让它返回任何东西。

有人有我可以遵循的工作示例吗?

【问题讨论】:

  • 试试这个链接:visualbasic.happycodings.com/files-directories-drives/…,它列出了所有网站的所有cookie
  • 你能区分显示的 cookie 和没有显示的 cookie 吗?
  • @Tom 怎么区分?你想看清单吗?如果是这个问题,我可以告诉您缺少哪些。
  • 没错。如果你的脚本显示了其中一些而一些没有,那么必须有“为什么”的答案。 :)
  • @Ryan Wildry...还请注意,使用 InternetGetCookie 有这些限制...没有到期日期的 Cookie 存储在内存中,并且仅可用于创建它们的进程。如 HTTP Cookies 主题中所述,InternetGetCookie 函数不会返回已被服务器标记为不可编写脚本的 cookie,并在 Set-Cookie 标头中使用“HttpOnly”属性。

标签: .net vba cookies


【解决方案1】:

尝试从shell:cookies 文件夹中检索 IE cookie。以下面的代码为例:

Option Explicit

Sub GetIECookies()

    Dim sCookiesPath As String
    Dim oCookies As Object
    Dim oFSO As Object
    Dim oFolder As Object
    Dim oFile
    Dim sContent As String
    Dim a() As String
    Dim i As Long
    Dim aItems
    Dim aCookies()

    ' read IE cookie files
    sCookiesPath = CreateObject("shell.application").Namespace("shell:Cookies").self.Path
    Set oCookies = CreateObject("Scripting.Dictionary")
    Set oFSO = CreateObject("Scripting.FileSystemObject")
    Set oFolder = oFSO.GetFolder(sCookiesPath)
    For Each oFile In oFolder.Files
        If LCase(oFSO.GetExtensionName(oFile.Name)) = "txt" Then
            With oFile.OpenAsTextStream(1, 0) ' read-only, ascii
                sContent = .ReadAll
                .Close
            End With
            sContent = Replace(sContent, vbCr, "")
            ' split cookies within file
            a = Split(sContent, vbLf & "*" & vbLf)
            For i = 0 To UBound(a) - 1
                oCookies.Add oCookies.Count, a(i)
            Next
        End If
    Next
    ' parse data, repack to 2d array
    aItems = oCookies.Items()
    If UBound(aItems) = -1 Then
        MsgBox "No cookies found"
    Else
        ReDim aCookies(1 To UBound(aItems) + 1, 1 To 6)
        For i = 1 To UBound(aItems) + 1
            a = Split(aItems(i - 1), vbLf)
            aCookies(i, 1) = a(0)
            aCookies(i, 2) = a(1)
            aCookies(i, 3) = a(2)
            aCookies(i, 4) = GetInetCookieFlags(a(3))
            aCookies(i, 5) = ConvDT(a(4), a(5))
            aCookies(i, 6) = ConvDT(a(6), a(7))
        Next
        ' output
        With ThisWorkbook.Sheets(1)
            .Cells.Delete
            .Range("A1:F1") = Array("Name", "Value", "Host/Path", "Flags", "Expiration", "Created")
            Output .Range("A2"), aCookies
        End With
    End If

End Sub

Function ConvDT(sLowNTFmt As String, sHighNTFmt As String) As Date

    Dim dNTFmt As Double
    Dim dUnixFmt As Double

    ' FILETIME format is the number of 100 nanosecond ticks since 00:00 1 Jan, 1601 (UTC).
    dNTFmt = sHighNTFmt * 4294967296# + sLowNTFmt
    ' Unix time format is the number of seconds since 00:00 1 Jan 1970
    dUnixFmt = 0.0000001 * dNTFmt - 11644473600#
    ' VB time format is the number of days since 00:00 1 Jan 1900
    ConvDT = CDate(dUnixFmt / 86400 + 25569)

End Function

Function GetInetCookieFlags(sFlags As String) As String

    Dim lFlags As Long
    Dim aFlag

    ' reset bit 32 to avoid overflow
    If sFlags >= 2147483648# Then lFlags = CLng(sFlags - 2147483648#) Else lFlags = CLng(sFlags)
    ' convert flags bits to string representation
    With CreateObject("Scripting.Dictionary")
        For Each aFlag In Array( _
            Array(&H1, "IS SECURE"), _
            Array(&H2, "IS SESSION"), _
            Array(&H10, "THIRD PARTY"), _
            Array(&H20, "PROMPT REQUIRED"), _
            Array(&H40, "EVALUATE P3P"), _
            Array(&H80, "APPLY P3P"), _
            Array(&H100, "P3P ENABLED"), _
            Array(&H200, "IS RESTRICTED"), _
            Array(&H400, "IE6"), _
            Array(&H800, "IS LEGACY"), _
            Array(&H1000, "NON SCRIPT"), _
            Array(&H2000, "HTTPONLY"), _
            Array(&H4000, "HOST ONLY"), _
            Array(&H8000, "APPLY HOST ONLY"), _
            Array(&H20000, "RESTRICTED ZONE"), _
            Array(&H20000000, "ALL COOKIES"), _
            Array(&H40000000, "NO CALLBACK"), _
            Array(&H80000000, "ECTX 3RDPARTY") _
        )
            If lFlags And aFlag(0) Then .Add .Count, aFlag(1)
        Next
        GetInetCookieFlags = Join(.Items(), vbCrLf)
    End With

End Function

Sub Output(oDstRng As Range, aCells As Variant)

    With oDstRng
        .Parent.Select
        With .Resize( _
            UBound(aCells, 1) - LBound(aCells, 1) + 1, _
            UBound(aCells, 2) - LBound(aCells, 2) + 1 _
        )
            .NumberFormat = "@"
            .Value = aCells
            .Columns.AutoFit
        End With
    End With

End Sub

删除所有 cookie 并导航到 https://stackoverflow.com/ 后,我的输出如下:

关于代码的一些注释。

它只解析Cookies\ 文件夹中的文件,但不解析Cookies\Low\ 中的文件,该文件用于在低权限下运行的应用程序。它只检索存储在文件夹中的持久性 cookie,而不检索存储在内存中的会话 cookie,并且只能由创建它们的进程访问。时间为 UTC。

文件中cookie的结构如下:

Cookie name
Cookie value
Host/path for the web server setting the cookie
Flags
Exirpation time (low)
Expiration time (high)
Creation time (low)
Creation time (high)
Record delimiter (*)

标志按照wininet.dll headers定义:

#define INTERNET_COOKIE_IS_SECURE                0x00000001
#define INTERNET_COOKIE_IS_SESSION               0x00000002
#define INTERNET_COOKIE_THIRD_PARTY              0x00000010
#define INTERNET_COOKIE_PROMPT_REQUIRED          0x00000020
#define INTERNET_COOKIE_EVALUATE_P3P             0x00000040
#define INTERNET_COOKIE_APPLY_P3P                0x00000080
#define INTERNET_COOKIE_P3P_ENABLED              0x00000100
#define INTERNET_COOKIE_IS_RESTRICTED            0x00000200
#define INTERNET_COOKIE_IE6                      0x00000400
#define INTERNET_COOKIE_IS_LEGACY                0x00000800
#define INTERNET_COOKIE_NON_SCRIPT               0x00001000
#define INTERNET_COOKIE_HTTPONLY                 0x00002000
#define INTERNET_COOKIE_HOST_ONLY                0x00004000
#define INTERNET_COOKIE_APPLY_HOST_ONLY          0x00008000
#define INTERNET_COOKIE_RESTRICTED_ZONE          0x00020000
#define INTERNET_COOKIE_ALL_COOKIES              0x20000000
#define INTERNET_COOKIE_NO_CALLBACK              0x40000000
#define INTERNET_COOKIE_ECTX_3RDPARTY            0x80000000

【讨论】:

  • 它是否仅从 IE、IE Edge 或 Safari、Google chrome、Chromium、Firefox、Opera 获取 cookie?
  • @YumYumYum 仅适用于 IE。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-02
  • 2016-05-30
  • 1970-01-01
  • 1970-01-01
  • 2013-03-16
  • 1970-01-01
相关资源
最近更新 更多