Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

authenticated http client requests from golang

Tags:

http

go

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 ?

like image 847
Sankar Avatar asked Jul 06 '12 11:07

Sankar


People also ask

What is http client in golang?

Golang HTTP Performance. HTTP (hypertext transfer protocol) is a communication protocol that transfers data between client and server. HTTP requests are very essential to access resources from the same or remote server.

What is HTTP client authentication?

HTTPS Client Authentication is a more secure method of authentication than either basic or form-based authentication. It uses HTTP over SSL (HTTPS), in which the server authenticates the client using the client's Public Key Certificate (PKC).

How do you implement basic auth in Golang?

Creating the HTTP server Now we will add a check for basic auth in the greeting handler. If you look at the above carefully, you will see we are using the r. BasicAuth() method to extract the username password. Here is the method signature func (r *Request) BasicAuth() (username, password string, ok bool) .


2 Answers

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.

like image 50
Sankar Avatar answered Sep 19 '22 06:09

Sankar


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.

like image 29
Mike Reedell Avatar answered Sep 18 '22 06:09

Mike Reedell