33

I have the following code:

client := &http.Client{}

/* Authenticate */
req, err := http.NewRequest("GET", "http://164.99.113.32/Authenticate", nil)
req.SetBasicAuth("<username>","<password>")
resp, err := client.Do(req)
if err != nil {
    fmt.Printf("Error : %s", err)
}

/* Get Details */
req.URL, _ = url.Parse("http://164.99.113.32/Details")
resp, err = client.Do(req)
if err != nil {
    fmt.Printf("Error : %s", err)
}

Now, the second http call is failing with a 401 access-denied error. A different REST client (a firefox plugin) correctly gets the details from the server, so I know that nothing is wrong on the server side. Do I need to pass some kind of session string or something that we got in the previous request ?

Ivan Vinogradov
  • 4,269
  • 6
  • 29
  • 39
Sankar
  • 6,192
  • 12
  • 65
  • 89

3 Answers3

25

Okay. I have resolved this. I just needed to create a cookie jar.

I am surprised that this is not handled by default by the golang http req/client class.

The code that I had to use was:

type myjar struct {
    jar map[string] []*http.Cookie
}

func (p* myjar) SetCookies(u *url.URL, cookies []*http.Cookie) {
    fmt.Printf("The URL is : %s\n", u.String())
    fmt.Printf("The cookie being set is : %s\n", cookies)
    p.jar [u.Host] = cookies
}

func (p *myjar) Cookies(u *url.URL) []*http.Cookie {
    fmt.Printf("The URL is : %s\n", u.String())
    fmt.Printf("Cookie being returned is : %s\n", p.jar[u.Host])
    return p.jar[u.Host]
}

and then in main:

    jar := &myjar{}
    jar.jar = make(map[string] []*http.Cookie)
    client.Jar = jar

Works.

Sankar
  • 6,192
  • 12
  • 65
  • 89
14

With HTTP Basic Authentication, the credentials are required for every request. Try copying the

req.SetBasicAuth("<username>", "<password>")

line before the second client.Do(req).

The reason the Firefox plugin gets the details is that the browser will cache HTTP Basic Authentication tokens for subsequent use.

Mike Reedell
  • 1,567
  • 15
  • 23
  • Is that method validates whether password is correct? In my case it fails silently when I passed incorrect password. – laimison Jan 02 '19 at 10:18
  • I can answer to my own question. This can be solved with `resp, err = client.Do(req)` `defer resp.Body.close()` and `if resp.StatusCode != 200 { log.Fatal("HTTP response code is not 200") }`. So it's possible to track the response using this method. – laimison Jan 02 '19 at 10:31
4

There is a new official library, maybe this is helpful.

http://golang.org/pkg/net/http/cookiejar/

example: Golang: how to follow location with cookie

Community
  • 1
  • 1
Daniel YC Lin
  • 15,050
  • 18
  • 63
  • 96