Implementing Authentication in a Go Web Application

Table of Contents

  1. Introduction
  2. Prerequisites
  3. Setting Up the Go Web Application
  4. Implementing Authentication
  5. Conclusion

Introduction

In this tutorial, we will learn how to implement authentication in a Go web application. Authentication is a crucial aspect of building secure web applications that require user-specific functionality. By the end of this tutorial, you will have a clear understanding of how to handle user authentication in your Go web applications.

Prerequisites

Before getting started, you should have a basic understanding of the Go programming language and web application development. Additionally, you will need to have Go and a text editor installed on your machine.

Setting Up the Go Web Application

Let’s start by setting up the basic structure of our Go web application.

  1. Create a new directory on your machine for your project: mkdir my-web-app.
  2. Navigate into the project directory: cd my-web-app.
  3. Initialize Go modules: go mod init example.com/my-web-app.
  4. Create a main Go file main.go: touch main.go.

  5. Open main.go in your text editor.

     package main
        
     import (
     	"fmt"
     	"net/http"
     )
        
     func main() {
     	http.HandleFunc("/", handler)
     	http.ListenAndServe(":8080", nil)
     }
        
     func handler(w http.ResponseWriter, r *http.Request) {
     	fmt.Fprintf(w, "Welcome to my web app!")
     }
    

    In this code, we have set up a basic HTTP server that listens on port 8080 and responds with a “Welcome to my web app!” message. Let’s proceed to implement authentication.

Implementing Authentication

To implement authentication, we will use the concept of sessions and store session tokens in cookies. We will use the github.com/gorilla/sessions package to simplify session management.

  1. Install the Gorilla sessions package: go get github.com/gorilla/sessions.

  2. Open main.go in your text editor.

     package main
        
     import (
     	"fmt"
     	"net/http"
        
     	"github.com/gorilla/mux"
     	"github.com/gorilla/sessions"
     )
        
     var store = sessions.NewCookieStore([]byte("super-secret-key"))
        
     func main() {
     	r := mux.NewRouter()
     	r.HandleFunc("/", handler)
     	r.HandleFunc("/login", loginHandler).Methods("POST")
     	r.HandleFunc("/logout", logoutHandler)
     	http.ListenAndServe(":8080", r)
     }
        
     func handler(w http.ResponseWriter, r *http.Request) {
     	session, _ := store.Get(r, "session-name")
     	if auth, ok := session.Values["authenticated"].(bool); !ok || !auth {
     		http.Redirect(w, r, "/login", http.StatusSeeOther)
     		return
     	}
        
     	fmt.Fprintf(w, "Welcome to my web app!")
     }
        
     func loginHandler(w http.ResponseWriter, r *http.Request) {
     	username := r.FormValue("username")
     	password := r.FormValue("password")
        
     	if username == "admin" && password == "password" {
     		session, _ := store.Get(r, "session-name")
     		session.Values["authenticated"] = true
     		session.Save(r, w)
     		http.Redirect(w, r, "/", http.StatusSeeOther)
     		return
     	}
        
     	http.Redirect(w, r, "/login", http.StatusSeeOther)
     }
        
     func logoutHandler(w http.ResponseWriter, r *http.Request) {
     	session, _ := store.Get(r, "session-name")
     	session.Values["authenticated"] = false
     	session.Save(r, w)
     	http.Redirect(w, r, "/login", http.StatusSeeOther)
     }
    

    In this updated code, we have added the Gorilla sessions package and modified our main function to use the Gorilla Mux router instead of the default HTTP router. We also added three new handler functions: loginHandler, logoutHandler, and an updated handler function.

    • The loginHandler function handles the authentication logic. It checks if the provided username and password match the expected values (“admin” and “password” in this example). If authentication is successful, it sets the “authenticated” session value to true and redirects the user to the main page. Otherwise, it redirects the user back to the login page.
    • The logoutHandler function simply sets the “authenticated” session value to false and redirects the user to the login page.
    • The updated handler function checks if the user is authenticated by retrieving the session value. If the user is not authenticated, it redirects them to the login page. Otherwise, it displays the “Welcome to my web app!” message.

    Now, when you access http://localhost:8080, you will be redirected to the login page. The login page can be a simple HTML form where the user enters their username and password.

Conclusion

In this tutorial, we have learned how to implement authentication in a Go web application using session management and cookies. By leveraging the Gorilla sessions package, we were able to handle user authentication and restrict access to certain parts of our web application. You can further enhance this implementation by integrating with a user database and implementing password hashing for enhanced security.