14 How to Build API Key Authentication Middleware with Unit Tests Using `httprouter` in Golang
APIs (Application Programming Interfaces) play a crucial role in connecting various applications or services. To ensure your application remains secure and protected from unauthorized access, implementing authentication methods such as API Key Authentication is essential. In this article, we will go through a step-by-step guide on how to create API Key Authentication middleware using httprouter in Golang, along with unit tests for each function to ensure reliability.
What is API Key Authentication Middleware?
Middleware is a software component that sits between the server and the application to process HTTP requests. In the context of APIs, API Key Authentication middleware verifies every request to ensure it contains a valid API key. This prevents API misuse by restricting access only to registered applications.
The middleware will check whether the API-Key header in the request matches a valid API key. If it is invalid, the request will be rejected with a 401 Unauthorized status.
Steps to Implement API Key Authentication Middleware
Here’s how to build API Key Authentication middleware with httprouter in Golang, including unit tests for each function.
1. Install httprouter Library
If you haven’t installed it yet, add the httprouter library by running:
1go get github.com/julienschmidt/httprouter2. Project Structure
A simple project structure looks like this:
1/go-api-key-auth
2 /main.go
3 /middleware.go
4 /middleware_test.gomain.go: The entry point of the application.middleware.go: Contains the API key authentication logic.middleware_test.go: Contains unit tests.
3. Implementing the Middleware
First, create the API Key Authentication middleware to validate API keys.
middleware.go
1package main
2
3import (
4 "net/http"
5 "github.com/julienschmidt/httprouter"
6)
7
8// validAPIKey is the pre-defined valid API key
9const validAPIKey = "1234567890"
10
11// APIKeyMiddleware is a middleware function to verify API Key in requests
12func APIKeyMiddleware(next httprouter.Handle) httprouter.Handle {
13 return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
14 apiKey := r.Header.Get("API-Key")
15
16 // Reject request if API key is missing or invalid
17 if apiKey != validAPIKey {
18 http.Error(w, "Unauthorized", http.StatusUnauthorized)
19 return
20 }
21
22 // Proceed to the next handler if the API key is valid
23 next(w, r, ps)
24 }
25}
26
27// protectedEndpoint is an API endpoint secured by API key authentication
28func protectedEndpoint(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
29 w.Write([]byte("Access granted to protected endpoint!"))
30}4. Implementing the Main Function
Now, create the main function to run the server and define routes for the protected endpoint.
main.go
1package main
2
3import (
4 "log"
5 "net/http"
6 "github.com/julienschmidt/httprouter"
7)
8
9func main() {
10 router := httprouter.New()
11
12 // Apply middleware to the protected endpoint
13 router.GET("/protected", APIKeyMiddleware(protectedEndpoint))
14
15 // Start the server
16 log.Fatal(http.ListenAndServe(":8080", router))
17}5. Writing Unit Tests
After implementing the middleware, we need to add unit tests to verify its functionality. These tests ensure that API key validation works correctly and the endpoint responds as expected.
middleware_test.go
1package main
2
3import (
4 "net/http"
5 "net/http/httptest"
6 "testing"
7 "github.com/julienschmidt/httprouter"
8)
9
10// Unit test for APIKeyMiddleware
11func TestAPIKeyMiddleware(t *testing.T) {
12 // Create router instance
13 router := httprouter.New()
14
15 // Attach protected handler with middleware
16 router.GET("/protected", APIKeyMiddleware(protectedEndpoint))
17
18 tests := []struct {
19 apiKey string
20 expectedCode int
21 }{
22 {"1234567890", http.StatusOK}, // Valid API key
23 {"invalid-api-key", http.StatusUnauthorized}, // Invalid API key
24 {"", http.StatusUnauthorized}, // Missing API key
25 }
26
27 for _, tt := range tests {
28 t.Run(tt.apiKey, func(t *testing.T) {
29 req, err := http.NewRequest("GET", "/protected", nil)
30 if err != nil {
31 t.Fatal(err)
32 }
33
34 // Add API Key to request header
35 req.Header.Set("API-Key", tt.apiKey)
36
37 // Create recorder to capture response
38 rr := httptest.NewRecorder()
39
40 // Serve request
41 router.ServeHTTP(rr, req)
42
43 // Check response status code
44 if rr.Code != tt.expectedCode {
45 t.Errorf("Expected status %v, got %v", tt.expectedCode, rr.Code)
46 }
47 })
48 }
49}Running the Unit Tests
To run the unit tests, execute the following command:
1go test -vIf all tests pass, you will see an output like this:
1=== RUN TestAPIKeyMiddleware
2--- PASS: TestAPIKeyMiddleware (0.00s)
3PASS
4ok <your-package-name> 0.004s6. Running the Server
To start the server, run:
1go run main.goThen, access the protected API using curl or any HTTP client.
Conclusion
By following this tutorial, you have successfully built API Key Authentication middleware using httprouter in Golang. You also implemented unit tests to ensure your middleware and application logic work correctly. Using middleware like this is essential for keeping your API secure and preventing unauthorized access.
For further learning on Golang, check out these related articles:
With this knowledge, you’re now ready to develop more secure and robust APIs!