pemrograman

18 Membuat Middleware Cors Menggunakan Httprouter Pada Golang

Cross-Origin Resource Sharing (CORS) adalah mekanisme keamanan yang memungkinkan atau membatasi permintaan HTTP dari domain yang berbeda. Dalam pengembangan aplikasi web, sering kali ada kebutuhan untuk berinteraksi dengan API yang tidak berasal dari domain yang sama dengan aplikasi. Oleh karena itu, middleware CORS dibutuhkan untuk mengontrol dan memberikan izin akses dari sumber lain untuk memastikan bahwa permintaan dari berbagai origin dapat diterima dan dijawab oleh server dengan aman.

Pada artikel ini, kita akan membahas bagaimana cara membuat middleware CORS di Go menggunakan library httprouter. Artikel ini juga akan mencakup cara membuat unit test untuk middleware ini agar lebih mudah dipahami oleh pemula dalam pengembangan aplikasi web di Go.

Langkah 1: Menyiapkan Proyek Golang

Langkah pertama adalah menyiapkan proyek Golang dan menambahkan dependensi yang diperlukan. Di sini kita akan menggunakan httprouter untuk menangani routing HTTP.

Langkah 1.1: Install Library httprouter

Untuk memulai, pastikan Golang telah terinstall. Kemudian buat folder proyek dan masuk ke folder tersebut:

mkdir cors-middleware
cd cors-middleware

Buat file go.mod dengan menjalankan perintah ini:

go mod init cors-middleware

Install dependensi httprouter:

go get github.com/julienschmidt/httprouter

Setelah dependensi terinstal, kita bisa mulai membuat kode.

Langkah 1.2: Menyiapkan Routing di Main

Buat file main.go dengan kode berikut:

package main

import (
	"log"
	"net/http"
	"github.com/julienschmidt/httprouter"
)

// Define CORS middleware function
func CORSMiddleware(next httprouter.Handle) httprouter.Handle {
	return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
		// Allow all origins, methods, and headers by default
		w.Header().Set("Access-Control-Allow-Origin", "*")
		w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
		w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
		w.Header().Set("Access-Control-Allow-Credentials", "true")

		// If it's an OPTIONS request, respond with 200 immediately
		if r.Method == http.MethodOptions {
			w.WriteHeader(http.StatusOK)
			return
		}

		// Call the next handler
		next(w, r, ps)
	}
}

func main() {
	router := httprouter.New()

	// Apply middleware to a specific route
	router.GET("/", CORSMiddleware(func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
		w.Write([]byte("Hello, world!"))
	}))

	log.Fatal(http.ListenAndServe(":8080", router))
}

Penjelasan:

  1. Middleware CORSMiddleware: Fungsi middleware ini menambahkan header CORS pada respons HTTP dan memeriksa metode HTTP OPTIONS untuk mengizinkan preflight request.
  2. Handler Route: Middleware ini diterapkan pada handler GET di root (/). Jika ada permintaan OPTIONS, server akan mengembalikan status 200.
  3. Running the Server: Pada akhir kode, server akan dijalankan pada port 8080 dengan menggunakan httprouter.

Langkah 2: Menambahkan Unit Test untuk Middleware CORS

Selanjutnya, kita akan menambahkan unit test untuk memverifikasi bahwa middleware kita bekerja dengan benar. Kita menggunakan library net/http/httptest untuk menguji response dari middleware yang kita buat.

Langkah 2.1: Membuat File Unit Test

Buat file baru dengan nama main_test.go untuk menulis unit test.

package main

import (
	"net/http"
	"net/http/httptest"
	"testing"
)

// TestCORSHeader tests that the CORS headers are set correctly
func TestCORSHeader(t *testing.T) {
	// Create a new httptest server
	handler := CORSMiddleware(func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
		w.Write([]byte("Test"))
	})

	req, _ := http.NewRequest("GET", "/", nil)
	rr := httptest.NewRecorder()

	// Call the handler
	handler(rr, req, nil)

	// Check the CORS headers
	if rr.Header().Get("Access-Control-Allow-Origin") != "*" {
		t.Errorf("Expected Access-Control-Allow-Origin header to be '*', got %s", rr.Header().Get("Access-Control-Allow-Origin"))
	}
	if rr.Header().Get("Access-Control-Allow-Methods") != "GET, POST, PUT, DELETE, OPTIONS" {
		t.Errorf("Expected Access-Control-Allow-Methods header to be 'GET, POST, PUT, DELETE, OPTIONS', got %s", rr.Header().Get("Access-Control-Allow-Methods"))
	}
	if rr.Header().Get("Access-Control-Allow-Headers") != "Content-Type, Authorization" {
		t.Errorf("Expected Access-Control-Allow-Headers header to be 'Content-Type, Authorization', got %s", rr.Header().Get("Access-Control-Allow-Headers"))
	}
}

// TestOPTIONSRequest tests that OPTIONS requests are handled correctly
func TestOPTIONSRequest(t *testing.T) {
	handler := CORSMiddleware(func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
		w.Write([]byte("Test"))
	})

	req, _ := http.NewRequest("OPTIONS", "/", nil)
	rr := httptest.NewRecorder()

	// Call the handler
	handler(rr, req, nil)

	// Check status code for OPTIONS request
	if rr.Code != http.StatusOK {
		t.Errorf("Expected status 200 OK, got %d", rr.Code)
	}
}

// TestCORSMethodHeader checks for correct method headers
func TestCORSMethodHeader(t *testing.T) {
	handler := CORSMiddleware(func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
		w.Write([]byte("Test"))
	})

	req, _ := http.NewRequest("POST", "/", nil)
	rr := httptest.NewRecorder()

	// Call the handler
	handler(rr, req, nil)

	// Check the method header
	if rr.Header().Get("Access-Control-Allow-Methods") != "GET, POST, PUT, DELETE, OPTIONS" {
		t.Errorf("Expected Access-Control-Allow-Methods to include POST, got %s", rr.Header().Get("Access-Control-Allow-Methods"))
	}
}

Penjelasan Unit Test:

  • TestCORSHeader: Menguji apakah header CORS sudah diset dengan benar (termasuk Access-Control-Allow-Origin, Access-Control-Allow-Methods, dan Access-Control-Allow-Headers).
  • TestOPTIONSRequest: Memverifikasi bahwa untuk permintaan OPTIONS, server akan merespons dengan status 200.
  • TestCORSMethodHeader: Menguji bahwa header Access-Control-Allow-Methods termasuk metode HTTP yang sesuai (seperti POST).

Untuk menjalankan unit test ini, gunakan perintah:

go test

Langkah 3: Menjalankan Aplikasi

Sekarang, Anda bisa menjalankan aplikasi menggunakan perintah:

go run main.go

Kunjungi http://localhost:8080 untuk melihat hasil dari aplikasi. Anda akan melihat respons “Hello, world!” dan dapat memverifikasi bahwa CORS bekerja dengan menggunakan alat pengembang di browser untuk memeriksa header.

Kesimpulan

Membangun middleware CORS di Go menggunakan httprouter sangatlah mudah dan memberikan fleksibilitas penuh dalam mengontrol bagaimana aplikasi berinteraksi dengan origin lain. Dengan menggunakan unit test, kita memastikan bahwa middleware yang dibangun berfungsi dengan baik dan sesuai dengan yang diinginkan. Anda bisa menambahkan lebih banyak aturan dan fitur sesuai dengan kebutuhan aplikasi.

Jangan ragu untuk mengeksplorasi dokumentasi lainnya:

comments powered by Disqus