Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases now! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Go Web Development Cookbook

You're reading from   Go Web Development Cookbook Build full-stack web applications with Go

Arrow left icon
Product type Paperback
Published in Apr 2018
Publisher Packt
ISBN-13 9781787286740
Length 338 pages
Edition 1st Edition
Languages
Tools
Arrow right icon
Author (1):
Arrow left icon
Arpit Aggarwal Arpit Aggarwal
Author Profile Icon Arpit Aggarwal
Arpit Aggarwal
Arrow right icon
View More author details
Toc

Table of Contents (13) Chapters Close

Preface 1. Creating Your First Server in Go 2. Working with Templates, Static Files, and HTML Forms FREE CHAPTER 3. Working with Sessions, Error Handling, and Caching in Go 4. Writing and Consuming RESTful Web Services in Go 5. Working with SQL and NoSQL Databases 6. Writing Microservices in Go Using Micro – a Microservice Toolkit 7. Working with WebSocket in Go 8. Working with the Go Web Application Framework – Beego 9. Working with Go and Docker 10. Securing a Go Web Application 11. Deploying a Go Web App and Docker Containers to AWS 12. Other Books You May Enjoy

Implementing basic authentication on a simple HTTP server

Once you have created the HTTP server then you probably want to restrict resources from being accessed by a specific user, such as the administrator of an application. If so, then you can implement basic authentication on an HTTP server, which we will be covering in this recipe.

Getting ready

As we have already created an HTTP server in our previous recipe, we will just extend it to incorporate basic authentication.

How to do it...

In this recipe, we are going to update the HTTP server we created in the previous recipe by adding a BasicAuth function and modifying the HandleFunc to call it. Perform the following steps:

  1. Create http-server-basic-authentication.go and copy the following content:
package main
import
(
"crypto/subtle"
"fmt"
"log"
"net/http"
)
const
(
CONN_HOST = "localhost"
CONN_PORT = "8080"
ADMIN_USER = "admin"
ADMIN_PASSWORD = "admin"
)
func helloWorld(w http.ResponseWriter, r *http.Request)
{
fmt.Fprintf(w, "Hello World!")
}
func BasicAuth(handler http.HandlerFunc, realm string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request)
{
user, pass, ok := r.BasicAuth()
if !ok || subtle.ConstantTimeCompare([]byte(user),
[]byte(ADMIN_USER)) != 1||subtle.ConstantTimeCompare([]byte(pass),
[]byte(ADMIN_PASSWORD)) != 1
{
w.Header().Set("WWW-Authenticate", `Basic realm="`+realm+`"`)
w.WriteHeader(401)
w.Write([]byte("You are Unauthorized to access the
application.\n"))
return
}
handler(w, r)
}
}
func main()
{
http.HandleFunc("/", BasicAuth(helloWorld, "Please enter your
username and password"))
err := http.ListenAndServe(CONN_HOST+":"+CONN_PORT, nil)
if err != nil
{
log.Fatal("error starting http server : ", err)
return
}
}
  1. Run the program with the following command:
$ go run http-server-basic-authentication.go

How it works...

Once we run the program, the HTTP server will start locally listening on port 8080.

Once the server starts, accessing http://localhost:8080 in a browser will prompt you to enter a username and password. Providing it as admin, admin respectively will render Hello World! on the screen, and for every other combination of username and password it will render You are Unauthorized to access the application.

To access the server from the command line we have to provide the --user flag as part of the curl command, as follows:

$ curl --user admin:admin http://localhost:8080/
Hello World!

We can also access the server using a base64 encoded token of username:password, which we can get from any website, such as https://www.base64encode.org/, and pass it as an authorization header in the curl command, as follows:

$ curl -i -H 'Authorization:Basic YWRtaW46YWRtaW4=' http://localhost:8080/

HTTP/1.1 200 OK

Date: Sat, 12 Aug 2017 12:02:51 GMT
Content-Length: 12
Content-Type: text/plain; charset=utf-8
Hello World!

Let’s understand the change we introduced as part of this recipe:

  • The import function adds an additional package, crypto/subtle, which we will use to compare the username and password from the user's entered credentials.
  • Using the const function we defined two additional constants, ADMIN_USER and ADMIN_PASSWORD, which we will use while authenticating the user.
  • Next, we declared a BasicAuth() method, which accepts two input parameters—a handler, which executes after the user is successfully authenticated, and realm, which returns HandlerFunc, as follows:
func BasicAuth(handler http.HandlerFunc, realm string) http.HandlerFunc 
{
return func(w http.ResponseWriter, r *http.Request)
{
user, pass, ok := r.BasicAuth()
if !ok || subtle.ConstantTimeCompare([]byte(user),
[]byte(ADMIN_USER)) != 1||subtle.ConstantTimeCompare
([]byte(pass),
[]byte(ADMIN_PASSWORD)) != 1
{
w.Header().Set("WWW-Authenticate", `Basic realm="`+realm+`"`)
w.WriteHeader(401)
w.Write([]byte("Unauthorized.\n"))
return
}
handler(w, r)
}
}

In the preceding handler, we first get the username and password provided in the request's authorization header using r.BasicAuth() then compare it to the constants declared in the program. If credentials match, then it returns the handler, otherwise it sets WWW-Authenticate along with a status code of 401 and writes You are Unauthorized to access the application on an HTTP response stream.

Finally, we introduced a change in the main() method to call BasicAuth from HandleFunc, as follows:

http.HandleFunc("/", BasicAuth(helloWorld, "Please enter your username and password"))

We just pass a BasicAuth handler instead of nil or DefaultServeMux for handling all incoming requests with the URL pattern as /.

lock icon The rest of the chapter is locked
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime