Table of Contents
In modern web development, securing APIs and web applications is essential. Go, known for its simplicity and performance, offers developers the flexibility to create custom middleware for authentication. This guide provides a step-by-step approach to building a robust authentication middleware in Go.
Understanding Middleware in Go
Middleware in Go acts as a layer that intercepts HTTP requests before they reach your handler functions. It allows you to perform actions such as authentication, logging, or modifying requests and responses. Creating custom middleware enables tailored security measures suited to your application's needs.
Prerequisites
- Basic knowledge of Go programming language
- Understanding of HTTP protocols
- Go environment setup with a working GOPATH
- Familiarity with net/http package
Step 1: Setting Up the Project
Create a new directory for your project and initialize a Go module:
mkdir auth-middleware
cd auth-middleware
go mod init auth-middleware
Step 2: Creating the Authentication Middleware
Define a middleware function that checks for a valid token in the request headers. If the token is valid, allow the request to proceed; otherwise, respond with an unauthorized status.
package main
import (
"net/http"
"strings"
)
// AuthMiddleware is a custom middleware for authentication
func AuthMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
authHeader := r.Header.Get("Authorization")
if authHeader == "" || !strings.HasPrefix(authHeader, "Bearer ") {
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte("Unauthorized"))
return
}
token := strings.TrimPrefix(authHeader, "Bearer ")
if !validateToken(token) {
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte("Invalid token"))
return
}
next.ServeHTTP(w, r)
})
}
// validateToken checks if the provided token is valid
func validateToken(token string) bool {
// Placeholder for token validation logic
// In real scenarios, verify token signature, expiry, etc.
return token == "valid-token"
}
Step 3: Creating Handlers and Applying Middleware
Define your route handlers and wrap them with the authentication middleware.
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/public", publicHandler)
mux.Handle("/private", AuthMiddleware(http.HandlerFunc(privateHandler)))
http.ListenAndServe(":8080", mux)
}
func publicHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Public Content"))
}
func privateHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Private Content - Authenticated"))
}
Step 4: Running the Application
Execute your application and test the endpoints using tools like curl or Postman. Ensure that the protected route requires the correct token.
go run main.go
Test with valid token:
curl -H "Authorization: Bearer valid-token" http://localhost:8080/private
Test with invalid or missing token:
curl http://localhost:8080/private
Conclusion
Building a custom authentication middleware in Go provides flexibility and control over your application's security. By intercepting requests and verifying tokens, you can ensure that only authorized users access sensitive routes. Extend this basic example with more sophisticated token validation, such as JWT verification, for enhanced security.