Implementing HTTP Basic Authentication in Golang

Basic access authentication uses standard fields in the HTTP headers for providing user credentials. It is the simplest technique for enforcing access control to web resources. It does not require cookies or session identifier or login page.

The specifications for basic access authentication are specified in RFC7617

For Golang httpauth package provides HTTP Basic Authentication middleware.

Installation

$ go get github.com/goji/httpauth

Usage

In this example I have used it with vanilla net/http. As given in the documentation the sample code is as follows.

Server

package main

import(
    "fmt"
    "net/http"
    "github.com/goji/httpauth"
)

func YourHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "some message to authenticated user.")
}

func main() {
    http.Handle("/", httpauth.SimpleBasicAuth("someuser", "somepassword")(http.HandlerFunc(YourHandler)))
    http.ListenAndServe(":7000", nil)
}

The above code creates an HTTP server on port 7000.

You build and run this code using following commands.

$ go build authserver.go
$ ./authserver

To check if it is really asking for the password you can use curl

$ curl -k -u someuser:somepassword http://0.0.0.0:7000

If you wish to see all the headers generated by curl command you can use -v parameter in the command.

$ curl -k -u someuser:somepassword http://0.0.0.0:7000 -v

It generates the headers/output like this.

* Rebuilt URL to: http://0.0.0.0:7000/
*   Trying 0.0.0.0...
* TCP_NODELAY set
* Connected to 0.0.0.0 (127.0.0.1) port 7000 (#0)
* Server auth using Basic with user 'someuser'
> GET / HTTP/1.1
> Host: 0.0.0.0:7000
> Authorization: Basic c29tZXVzZXI6c29tZXBhc3N3b3Jk
> User-Agent: curl/7.55.1
> Accept: */*
> 
< HTTP/1.1 200 OK
< Content-Type: text/html; charset=utf-8
< Last-Modified: Wed, 04 Jul 2018 08:56:45 GMT
< Date: Wed, 04 Jul 2018 08:57:13 GMT
< Content-Length: 169
<
some message to authenticated user.
* Connection #0 to host 0.0.0.0 left intact

If you give invalid username or password in curl command it won’t return the message (which in this case is “some message to authenticated user.”).

Client

If you want to implement the client for this basic authentication server in golang here is the code for that.

package main

import(
    "fmt"
    "net/http"
    "io/ioutil"
    "log"
)

func basicAuth() string {
    var username string = "someuser"
    var passwd string = "somepassword"
    client := &http.Client{}
    req, err := http.NewRequest("GET", "http://0.0.0.0:7000", nil)
    req.SetBasicAuth(username, passwd)
    resp, err := client.Do(req)
    if err != nil{
        log.Fatal(err)
    }
    bodyText, err := ioutil.ReadAll(resp.Body)
    s := string(bodyText)
    return s
}

func main(){
    fmt.Println("requesting...")
    S := basicAuth()
    fmt.Println(S)
}

To build and use this client the commands are as follows.

$ go build authclient.go
$ ./authclient