我尝试使用 golang 登录网站的私人区域并提取一些信息,但我似乎不太正确。我设法获取登录页面以获取 csrf 令牌,然后我将 csrf 令牌与登录信息一起发布到登录页面,然后我就可以登录了。如果我停在这一点上,我可以看到我被重定向的页面。但是,从此时起的任何后续调用都会将我重定向回登录。代码package mainimport ( "github.com/PuerkitoBio/goquery" "io" _ "io/ioutil" "log" "net/http" "net/url" _ "strings" "sync")type Jar struct { sync.Mutex cookies map[string][]*http.Cookie}func NewJar() *Jar { jar := new(Jar) jar.cookies = make(map[string][]*http.Cookie) return jar}func (jar *Jar) SetCookies(u *url.URL, cookies []*http.Cookie) { jar.Lock() jar.cookies[u.Host] = cookies jar.Unlock()}func (jar *Jar) Cookies(u *url.URL) []*http.Cookie { return jar.cookies[u.Host]}func NewJarClient() *http.Client { return &http.Client{ Jar: NewJar(), }}func fetch(w http.ResponseWriter, r *http.Request) { // create the client client := NewJarClient() // get the csrf token req, _ := http.NewRequest("GET", "http://www.domain.com/login", nil) resp, err := client.Do(req) if err != nil { log.Fatal(err) } doc, err := goquery.NewDocumentFromResponse(resp) if err != nil { log.Fatal(err) } csrfToken := "" if val, ok := doc.Find(`head meta[name="csrf-token-value"]`).Attr("content"); ok { csrfToken = val } // post on the login form. resp, _ = client.PostForm("http://www.domain.com/login", url.Values{ "UserLogin[email]": {"the email"}, "UserLogin[password]": {"the password"}, "csrf_token": {csrfToken}, }) doc, err = goquery.NewDocumentFromResponse(resp) if err != nil { log.Fatal(err) }知道我在这里缺少什么吗?
1 回答
至尊宝的传说
TA贡献1789条经验 获得超10个赞
好的,问题是 cookie jar 实现,更具体地说是 SetCookies 函数,现在是:
func (jar *Jar) SetCookies(u *url.URL, cookies []*http.Cookie) {
jar.Lock()
jar.cookies[u.Host] = cookies
jar.Unlock()
}
这是错误的,因为新的 cookie 不会被添加到现有的 cookie 中,它们只会作为新的 cookie 丢弃旧的而添加。
似乎正确的方法是:
func (jar *Jar) SetCookies(u *url.URL, cookies []*http.Cookie) {
jar.Lock()
if _, ok := jar.cookies[u.Host]; ok {
for _, c := range cookies {
jar.cookies[u.Host] = append(jar.cookies[u.Host], c)
}
} else {
jar.cookies[u.Host] = cookies
}
jar.Unlock()
}
- 1 回答
- 0 关注
- 155 浏览
添加回答
举报
0/150
提交
取消