【问题标题】:Logging on to a website, How are Cookies involved?登录网站,如何使用 Cookie?
【发布时间】:2023-10-18 02:31:01
【问题描述】:

好的,所以我正在编写一个需要登录网站的程序,希望从中获取一些信息。

他是我的登录密码:

module Webscraper = 
    open System.Net
    open HtmlAgilityPack
    open Lolcr.Model
    open System.Collections.Specialized

    let logon = fun (address:string) studentNumber password->
        let upload values =
            let wc = new WebClient()
            wc.UploadValues (address, values)
        let ToNameValueCollection nvs =
            let col = new NameValueCollection()
            for nv in nvs do
                match nv with (n, v) -> col.Add(n, v);
            col
        let fields :List<string*string> = 
            ("v_studentid",studentNumber) ::
            ("v_studentpin", password) ::
            ("b3", "Login") :: []
            let resp = fields |> ToNameValueCollection |> upload;
            resp |> Array.map char |> System.String.Concat

//and for viewing a page within the site:
    let pageAt = fun (address : string) ->
        let getWebStream = 
            let req = HttpWebRequest.Create address
            let resp = req.GetResponse()
            resp.GetResponseStream

        let doc = new HtmlDocument()
        getWebStream() |> doc.Load;
        doc.DocumentNode

现在当我调用登录时,它会返回登录页面的文本,就好像我没有登录一样(可能因为登录会在浏览器中进行重定向) 当我在我感兴趣的页面上调用 PageAt 时,会返回“请登录”页面。

看看 Fiddler2 发生了什么:(其中 XXXX 和 YYYY 分别是 studentNumber 和密码):

//Via firefox    
POST https://server2.olcr.uwa.edu.au/olcrstudent/index.jsp HTTP/1.1
Host: server2.olcr.uwa.edu.au
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:9.0.1) Gecko/20100101 Firefox/9.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-gb,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Referer: https://server2.olcr.uwa.edu.au/olcrstudent/
Cookie: JSESSIONID=18F87DFEB1555A6FA644215FDAE5E506; __utma=55889711.14817822.1328281214.1328281214.1328281214.1; __utmz=55889711.1328281214.1.1.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=olcr%20uwa; __utmb=55889711.1.10.1328281214; __utmc=55889711
Content-Type: application/x-www-form-urlencoded
Content-Length: 53

v_studentid=XXXX&v_studentpin=YYYY&b3=Login


//From my program:
POST https://server2.olcr.uwa.edu.au/olcrstudent/index.jsp HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Host: server2.olcr.uwa.edu.au
Content-Length: 53
Expect: 100-continue
Connection: Keep-Alive

v_studentid=XXXX&v_studentpin=YYYY&b3=Login

所以与我看到的最大区别在于我没有发送任何 cookie (我实际上并不完全确定 cookie 是什么,想一想(我会查一下 s>(编辑:完成)))

那么我应该发送 cookie 吗? .net 中的机制是什么? 我应该做一些不同的事情,因为这是 HTTPS 吗?

【问题讨论】:

  • "所以与我看到的最大不同是我没有发送任何 cookie(我实际上并不完全确定 cookie 是什么,想一想(我会看看up))" 先做这个。如果需要,然后回来问一个问题。
  • 在...上拼写为“logging”
  • 我现在查了一下 cookie 到底是什么(我之前有一个模糊的理解),并且相信我的问题仍然是正确的。

标签: .net cookies f# httpwebrequest fiddler


【解决方案1】:

一般来说,当您登录一个网站时,您必须有某种方式让该网站在您从一个页面到另一个页面时进行跟踪。

这通常使用 cookie 或 URL 中的会话标识符来完成。

现在,您需要了解两种 cookie 之间的区别。

一个是会话 cookie,它保留在客户端计算机的内存中,然后在您关闭浏览器(或会话关闭)后消失。这些仅包含一个唯一标识符,该标识符引用服务器上的用户唯一会话实例。这使服务器可以通过每个子序列页面点击知道您是谁。

另一种类型的 cookie 是您专门设置的物理 cookie,以将特定变量保存在客户端计算机上的文本文件中。

如果您查看您的回复,您会看到对会话 ID 的引用,这意味着您在客户端计算机上确实有一个会话 cookie:

Cookie: JSESSIONID=18F87DFEB1555A6FA644215FDAE5E506; __utma=55889711.14817822.1328281214.1328281214.1328281214.1; __utmz=55889711.1328281214.1.1.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=olcr%20uwa; __utmb=55889711.1.10.1328281214; __utmc=55889711 

如果您曾经使用过会话,则默认情况下会在 asp.net 中创建此 cookie。

【讨论】:

  • 这个答案绝不会告诉 OP 如何保存 cookie 以便可以登录网站。
  • 在确保他了解 cookie 的真正含义后,我指出他已经在他的网站上使用了会话 cookie,并且它是由 .net 在使用会话时自动创建的。您会说我的回答中缺少哪些信息,值得一票否决?
  • 1) 我没有投反对票。 2) .Net WebRequests 默认没有 cookie 容器。 服务器可能会尝试给你一个会话cookie,但客户端需要持久化它,这就是OP需要知道如何做的事情。
  • 确实,我正在编写客户端,而不是服务器。我现在开始工作了,非常感谢您的意见。
【解决方案2】:

是的,通常您需要保留 cookie 才能登录网站。 一个 CookieAwareWebclient,例如来自:this blog, 让它变得简单。 F# 等效项是

type CookieAwareWebclient (cookies) = 
    inherit WebClient()
    member this.CookieContainer = cookies

    new () = new CookieAwareWebclient(new CookieContainer())

    override this.GetWebRequest (address:Uri) =
        let req = base.GetWebRequest address
        match req with 
        | :? HttpWebRequest as httpReq -> 
            httpReq.CookieContainer <- this.CookieContainer;
            upcast httpReq
        | _ -> req;

现在,只要您通过 same Webclient 执行所有 Web 请求(因此您必须使 Webclient 可在整个模块中访问,并更改 pageAt 以使用它) 你会没事的

【讨论】:

    最近更新 更多