Creating a Login System in Go

Table of Contents

  1. Introduction
  2. Prerequisites
  3. Setting Up the Project
  4. Creating the Login Form
  5. Handling Form Submission
  6. Adding User Authentication
  7. Conclusion

Introduction

In this tutorial, we will learn how to create a login system in Go. By the end of this tutorial, you will be able to create a web application with a login page where users can authenticate themselves before accessing protected resources.

To follow along with this tutorial, you should have a basic understanding of the Go programming language and some knowledge of web development concepts.

Prerequisites

Before we begin, make sure you have the following prerequisites:

  1. Go installed on your machine. You can download and install Go from the official website: https://golang.org/dl/

  2. Familiarity with HTML and basic web development concepts.

Setting Up the Project

Let’s start by setting up the project structure and dependencies.

  1. Create a new directory for your project: mkdir login-system
  2. Change into the project directory: cd login-system
  3. Initialize a new Go module: go mod init github.com/your-username/login-system

  4. Create a new file named main.go in the project directory.

    Now, we are ready to start building our login system.

Creating the Login Form

Open the main.go file and add the following code:

package main

import (
	"fmt"
	"html/template"
	"log"
	"net/http"
)

type LoginForm struct {
	Username string
	Password string
}

func main() {
	http.HandleFunc("/", loginHandler)
	log.Fatal(http.ListenAndServe(":8080", nil))
}

func loginHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method == "POST" {
		// Handle form submission
	} else {
		// Render the login form
		tmpl, err := template.ParseFiles("login.html")
		if err != nil {
			log.Fatal(err)
		}
		tmpl.Execute(w, nil)
	}
}

In the above code, we define a LoginForm struct to represent the form fields for the login page. The loginHandler function is responsible for rendering the login form and handling form submissions.

Create a new file named login.html in the same directory and add the following code:

<!DOCTYPE html>
<html>
<head>
    <title>Login</title>
</head>
<body>
    <h1>Login</h1>
    <form action="/" method="POST">
        <label for="username">Username:</label>
        <input type="text" id="username" name="username" required><br><br>
        <label for="password">Password:</label>
        <input type="password" id="password" name="password" required><br><br>
        <input type="submit" value="Login">
    </form>
</body>
</html>

This HTML code represents the login form with fields for username and password.

Handling Form Submission

Next, let’s handle the form submission in the loginHandler function.

func loginHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method == "POST" {
		r.ParseForm()
		username := r.Form.Get("username")
		password := r.Form.Get("password")

		// Check username and password against a database or any other storage mechanism

		if username == "admin" && password == "password" {
			fmt.Fprintf(w, "Login successful!")
		} else {
			fmt.Fprintf(w, "Login failed!")
		}
	} else {
		tmpl, err := template.ParseFiles("login.html")
		if err != nil {
			log.Fatal(err)
		}
		tmpl.Execute(w, nil)
	}
}

In the above code, we use r.ParseForm() to parse the form values submitted in the request. We then extract the values for the username and password fields using r.Form.Get("fieldName"). You can replace the check with a validation against a database or any other storage mechanism.

If the username and password match, we display a success message. Otherwise, we display a failure message.

Adding User Authentication

We have seen a basic implementation of the login system, but it lacks proper user authentication. Let’s see how we can implement user authentication using sessions.

First, we need to install the gorilla/sessions package by running the following command:

go get github.com/gorilla/sessions

Then, update the import section in main.go:

import (
	"fmt"
	"html/template"
	"log"
	"net/http"

	"github.com/gorilla/sessions"
)

// ...

var store = sessions.NewCookieStore([]byte("secret-key"))

Next, update the loginHandler function to handle user authentication:

func loginHandler(w http.ResponseWriter, r *http.Request) {
	session, _ := store.Get(r, "session")

	if r.Method == "POST" {
		r.ParseForm()
		username := r.Form.Get("username")
		password := r.Form.Get("password")

		// Check username and password against a database or any other storage mechanism

		if username == "admin" && password == "password" {
			session.Values["authenticated"] = true
			session.Save(r, w)
			fmt.Fprintf(w, "Login successful!")
		} else {
			fmt.Fprintf(w, "Login failed!")
		}
	} else {
		if session.Values["authenticated"] == true {
			fmt.Fprintf(w, "Already logged in!")
		} else {
			tmpl, err := template.ParseFiles("login.html")
			if err != nil {
				log.Fatal(err)
			}
			tmpl.Execute(w, nil)
		}
	}
}

In the updated code, we create a session store using the sessions.NewCookieStore([]byte("secret-key")) function. This function requires a secret key to encrypt the session data.

We retrieve the session using store.Get(r, "session"). If the login form is submitted correctly, we set authenticated to true in the session and save it using session.Save(r, w).

To check if the user is already authenticated, we use session.Values["authenticated"]. If the value is true, we display a message indicating that the user is already logged in.

Conclusion

In this tutorial, we have learned how to create a basic login system in Go. We started by creating the login form and handling form submissions. Later, we added user authentication using sessions. You can further enhance this system by integrating it with a database and adding features like registration and password reset.

Remember to always secure your login system by following best practices, such as using secure encryption for passwords and protecting against common security vulnerabilities.

Now that you have a basic understanding of how to create a login system in Go, you can apply this knowledge to build more complex web applications and systems. Happy coding!