Go, Gin and HTTP / Basic Auth

I've been dabbling with Go and more specifically gin again and I needed a very quick and dirty authentication for a pet project.

Typically I don't recommend HTTP / basic auth to protect resources, but for this project I didn't have a database and I was just serving some markdown files here and there.

gin is one of my favourite web frameworks for go, because it has a lot of really cool middlewares, it's a bit like the express or hapi of go.

Installing Gin and Hello World

If you create a directory in your go/src folder, like gin-http-auth and in that a main.go file with the following content:

package main

import "github.com/gin-gonic/gin"

func main() {
    r := gin.Default()
    r.GET("/", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "Hello World!",
        })
    })
    r.Run() // listen and serve on 0.0.0.0:8080
}

Followed by running go get in your terminal, you're up and running! You now need to start your freshly baked JSON API by running:

go run main.go

and you should be seeing "message: Hello World!" in your browser at localhost:8080

Note: APIs are probably one of the bigger use cases for gin, but you can also render a range of templates directly.

Protecting Routes with Gin

Let's say you have something secret that you don't want everybody to see, whether it's a special recipe for your BBQ sauce or a love letter that contains... incriminating details!

We'll need to set up some example user accounts and create a secret route, unless of course we want to change the / route.

Let's have a look at the minimum viable example for this:

package main

import (
    "net/http"

    "github.com/gin-gonic/gin"
)

func main() {
    r := gin.Default()

    r.GET("/", func(c *gin.Context) {
        c.JSON(http.StatusOK, gin.H{
            "message": "Hello World!",
        })
    })

    authorized := r.Group("/", gin.BasicAuth(gin.Accounts{
        "user1": "love",
        "user2": "god",
        "user3": "sex",
    }))

    authorized.GET("/secret", func(c *gin.Context) {
        c.JSON(http.StatusOK, gin.H{
            "secret": "The secret ingredient to the BBQ sauce is stiring it in an old whiskey barrel.",
        })
    })

    r.Run() // listen and serve on 0.0.0.0:8080
}
  1. The import has changed, because we're using it for the http status codes
  2. the authorized "Group" has been added with example user data
  3. authorized.GET will only permit the users to enter that enter a correct combination. It's just like the normal router functions, but it requires authentication

When you have changed the file hit CTRL+C to quick your running Gin instance and restart it.

When you go to localhost:8080/secret in your browser now, you should see a window prompting you for username and password.

If you enter the credentials correctly, you'll see:

secret    "The secret ingredient to the BBQ sauce is stiring it in an old whiskey barrel."

That's all! You've created a dark den of secrets within your Go web project!

If you want more elaborate examples, check out the gin README.md on github, because it has a couple of really good examples!

Tagged with: #gin #go #golang

Thank you for reading! If you have any comments, additions or questions, please tweet or toot them at me!