Login Page in Go Using net/HTTP: From Templates to Authentication

before starting be sure you are familiar with HTTP methods (get, post, put, delete..), HTTP request and response writers, URLs, params, query, and formValue.
Step 1: Setting Up the Project Structure
Create the following project structure:
project_root/
├── static/
│ └── style.css
├── templates/
│ └── login.html
└── main.go
The static
directory will hold static files like CSS, JavaScript, images, etc. The templates
directory will contain the HTML template for the login page, and main.go
will be the main Go file.
Step 2: Implement the HTML Template
In the templates
directory, create a file named login.html
with the following content:
<!DOCTYPE html>
<html>
<head>
<title>Login Page</title>
<link rel="stylesheet" type="text/css" href="/static/style.css">
</head>
<body>
<div class="login-container">
<h2>Login</h2>
<form action="/login" method="POST">
<label for="username">Username:</label>
<input type="text" id="username" name="username" required><br>
<label for="password">Password:</label>
<input type="password" id="password" name="password" required><br>
<button type="submit">Login</button>
</form>
</div>
</body>
</html>
Step 3: Implement the CSS Styling
In the static
directory, create a file named style.css
with the following content:
body {
font-family: Arial, sans-serif;
background-color: #f0f0f0;
}
.login-container {
max-width: 300px;
margin: 100px auto;
padding: 20px;
background-color: #ffffff;
box-shadow: 0px 0px 10px #888888;
}
input[type="text"],
input[type="password"] {
width: 100%;
padding: 10px;
margin-bottom: 10px;
}
button {
background-color: #4CAF50;
color: white;
padding: 10px 20px;
border: none;
cursor: pointer;
width: 100%;
}
button:hover {
background-color: #45a049;
}
Step 4: Implement the Go Code
Now, let’s create the main.go
file with the following Go code:
package main
import (
"fmt"
"html/template"
"net/http"
)
func main() {
http.HandleFunc("/", LoginPage)
http.HandleFunc("/login", LoginPage)
http.HandleFunc("/welcome", WelcomePage)
// Serve static files from the "static" directory.
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
// Start the server on port 8080.
fmt.Println("Server started on http://localhost:8080")
http.ListenAndServe(":8080", nil)
}
func SignupPage(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodPost {
// Retrieve signup form data.
username := r.FormValue("username")
password := r.FormValue("password")
// Perform signup logic here (e.g., store user data in a database).
// For simplicity, we'll just print the data for demonstration.
fmt.Printf("New user signup: Username - %s, Password - %s\n", username, password)
// Redirect to a welcome or login page after signup.
http.Redirect(w, r, "/welcome", http.StatusSeeOther)
return
}
// If not a POST request, serve the signup page template.
tmpl, err := template.ParseFiles("templates/signup.html")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
tmpl.Execute(w, nil)
}
// LoginPage is the handler for the login page.
func LoginPage(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodPost {
username := r.FormValue("username")
password := r.FormValue("password")
// Perform authentication logic here (e.g., check against a database).
// For simplicity, we'll just check if the username and password are both "admin".
if username == "admin" && password == "admin" {
// Successful login, redirect to a welcome page.
http.Redirect(w, r, "/welcome", http.StatusSeeOther)
return
}
// Invalid credentials, show the login page with an error message.
fmt.Fprintf(w, "Invalid credentials. Please try again.")
return
}
// If not a POST request, serve the login page template.
tmpl, err := template.ParseFiles("templates/login.html")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
tmpl.Execute(w, nil)
}
// WelcomePage is the handler for the welcome page.
func WelcomePage(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Welcome, you have successfully logged in!")
}
Step 5: Explanation
- We define two handler functions:
LoginPage
andWelcomePage
. TheLoginPage
handles the GET and POST requests for the login page, while theWelcomePage
is a simple page to display a welcome message after successful login. - In
LoginPage
, when a POST request is made (form submission), we retrieve the values ofusername
andpassword
from the form usingr.FormValue()
. You should replace the authentication logic with proper checks against a user database or external authentication service. - The CSS styling is linked to the
login.html
template using the<link>
tag. The CSS file is served from the/static/
route using thehttp.FileServer()
. - In
main()
, we register the handlers for the respective routes usinghttp.HandleFunc()
. - The server is started using
http.ListenAndServe(":8080", nil)
.
Step 6: Run the Application
To run the application, open a terminal, navigate to the project_root
, and execute the following command:
go run main.go
Your server will start on http://localhost:8080
. Access this URL in your browser, and you should see the login page. You can use the username "admin" and the password "admin" to log in successfully.
Remember that this example uses a very basic authentication mechanism for demonstration purposes only. In a real-world scenario, you should implement more robust authentication and security measures.
Thank you for reading until the end. Please consider following the writer and this publication. Visit Stackademic to find out more about how we are democratising free programming education around the world.