title: Use Golang to login to private site and pull info
body: <p>I try to use golang to login in a private area of a website and pull some info, but i don't quite seem to get it right.
  I manage to fetch the login page to get the csrf token, then i post the csrf token together with the login info to the login page and i login just fine. If i stop at this point, i can see the page where i am redirected. However, any subsequent calls from this point on will redirect me back to login.</p>
  
  <p>The code</p>
  
  <pre><code>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 &amp;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)
  }
  </code></pre>
  
  <p>Any idea what i am missing here ?</p>