0

我正在尝试让 Go 在网页上提交表单以模拟登录。从那里我尝试使用 cookie 来保持持久会话,以便再次调用子页面。

我能够毫无问题地成功登录,我只是在捕获返回服务器设置的 cookie 时遇到问题。我想知道是不是因为他们的登录脚本做了几个重定向?(我得到一个输出)。

任何想法为什么我没有赶上被退回的饼干?

这是我正在使用的代码:

 import (
    "crypto/tls"
    "fmt"
    "io/ioutil"
    "net/http"
    "net/url"
    "strings"
    "sync"
)

type Jar struct {
    lk      sync.Mutex
    cookies map[string][]*http.Cookie
}

var CookieJar *Jar

func NewJar() *Jar {
    jar := new(Jar)
    jar.cookies = make(map[string][]*http.Cookie)
    return jar
}

// SetCookies handles the receipt of the cookies in a reply for the
// given URL.  It may or may not choose to save the cookies, depending
// on the jar's policy and implementation.
func (jar *Jar) SetCookies(u *url.URL, cookies []*http.Cookie) {
    jar.lk.Lock()
    jar.cookies[u.Host] = cookies
    jar.lk.Unlock()
}

// Cookies returns the cookies to send in a request for the given URL.
// It is up to the implementation to honor the standard cookie use
// restrictions such as in RFC 6265.
func (jar *Jar) Cookies(u *url.URL) []*http.Cookie {
    return jar.cookies[u.Host]
}

func NewClient() *http.Client {
    tr := &http.Transport{
    TLSClientConfig: &tls.Config{InsecureSkipVerify: false},
}

    CookieJar = NewJar()
    client := &http.Client{
        Transport:     tr,
        CheckRedirect: nil,
        Jar:           CookieJar,
    }

    return client
 }

 func Login() {
    client := NewClient()

    api := "https://www.statuscake.com/App/"
    uri, _ := url.Parse("https://www.statuscake.com")

    fmt.Printf("uri: %s\n", uri)

    values := url.Values{}
    values.Add("username", username)
    values.Add("password", password)
    values.Add("Login", "yes")
    values.Add("redirect", "")
    str := values.Encode()
    req, err := http.NewRequest("POST", api, strings.NewReader(str))

    req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
    req.Header.Set("Accept", "text/html")
    req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.65 Safari/537.36")
    cookies := CookieJar.Cookies(uri)
    for i := 0; i < len(cookies); i++ {
        fmt.Printf("Cookie[%d]: %s", i, cookies[i])
        req.AddCookie(cookies[i])
    }

    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    fmt.Printf("Response: %v\n", resp)

    fmt.Printf("Response.Cookies: %v\n", resp.Cookies())

    cookies = resp.Cookies()
    CookieJar.SetCookies(uri, cookies)

    defer resp.Body.Close()

    if resp.StatusCode == 200 {
        fmt.Printf("\n\n-----\n")
        fmt.Println("HTTP Code: ", resp.StatusCode)
        fmt.Println("Response Cookies: ", resp.Cookies())
        fmt.Println("Request Headers: ", req.Header)
        fmt.Println("Request Cookies: ", req.Cookies())
        fmt.Println("Response Headers: ", resp.Header)
        fmt.Printf("-----\n\n")
    }
 }
4

1 回答 1

0

不确定问题到底出在哪里,但有两个注意事项:

  1. 如果您的客户端有一个工作 Jar,则无需使用 cookie 手动填充请求。客户端应该为您透明地处理所有 cookie 内容:它从响应中提取 cookie 并存储在 jar 中,并使用 jar 中的 cookie 填充响应(即使在重定向期间)。也许这会覆盖您手动设置的 cookie。

  2. 不要滚动您自己的 CookieJar 实现。Cookie 处理很糟糕(你可能相信我)。只需使用http://golang.org/pkg/net/http/cookiejar/可能与 code.google.com/p/go.net/publicsuffix 结合使用

于 2013-09-17T08:56:00.557 回答