Я пытаюсь использовать golang для входа в частную зону веб-сайта и вытаскивать некоторую информацию, но я не совсем понимаю, что это правильно. Мне удается получить страницу входа в систему, чтобы получить токен csrf, а затем я помещаю токен csrf вместе с информацией для входа на страницу входа в систему, и я просто вхожу в систему. Если я остановлюсь на этом этапе, я могу увидеть страницу, на которой я перенаправлен. Однако любые последующие вызовы с этого момента перенаправят меня обратно в систему.Используйте Golang для входа на приватный сайт и вытащите информацию
Код
package main
import (
"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)
}
// if i stop here then i can see just fine the dashboard where i am redirected after login.
// but if i continue and request a 3rd page, then i get the login page again,
// sign that i lose the cookies and i am redirected back
// html, _ := doc.Html()
// io.WriteString(w, html)
// return
// from this point on, any request will give me the login page once again.
// i am not sure why since the cookies should be set and sent on all requests
req, _ = http.NewRequest("GET", "http://www.domain.com/dashboard", nil)
resp, err = client.Do(req)
if err != nil {
log.Fatal(err)
}
doc, err = goquery.NewDocumentFromResponse(resp)
if err != nil {
log.Fatal(err)
}
html, _ := doc.Html()
io.WriteString(w, html)
}
func main() {
http.HandleFunc("/", fetch)
http.ListenAndServe("127.0.0.1:49721", nil)
}
Любая идея, что я здесь отсутствует?
Ваш 'Реализация CookieJar' выглядит хорошо для меня. Вы уверены, что 'client.PostForm' удалось? Вы игнорируете ошибку там/не проверяете код состояния, поэтому я считаю безопасным предположить, что что-то вне этого кода могло привести к сбою, например, к недопустимым учетным данным. – evanmcdonnal
@evanmcdonnal - Да, PostForm в порядке, никаких ошибок нет. – Twisted1919