Pada artikel kali ini, kita akan membahas langkah-langkah pembuatan middleware untuk Session-based Authentication menggunakan Golang dan library httprouter
. Middleware ini berguna untuk memvalidasi sesi pengguna di setiap request yang masuk ke aplikasi.
Apa itu Session-based Authentication?
Session-based authentication adalah metode otentikasi di mana pengguna login melalui aplikasi dan server menyimpan informasi tentang sesi pengguna dalam bentuk session ID yang disimpan di server atau dalam cookie di browser pengguna. Setiap kali pengguna mengakses resource yang dilindungi, server akan memverifikasi sesi tersebut.
Untuk contoh kali ini, kita akan menggunakan httprouter, sebuah router HTTP yang sangat cepat dan simpel di Golang, untuk membuat middleware autentikasi berbasis sesi.
Langkah 1: Persiapan Proyek Golang
Jika belum, pastikan proyek Golang telah disiapkan dengan langkah berikut:
- Buat direktori proyek di terminal atau melalui IDE favorit Anda.
- Inisialisasi proyek Go.
go mod init session-auth-example
Langkah 2: Menginstal Dependensi
Pertama, kita perlu menambahkan dependensi untuk httprouter dan beberapa dependensi lain yang dibutuhkan, seperti gorilla/sessions untuk menangani sesi pengguna.
Instalasi httprouter
dan gorilla/sessions
dapat dilakukan dengan menjalankan perintah:
go get github.com/julienschmidt/httprouter
go get github.com/gorilla/sessions
Langkah 3: Menyiapkan Middleware Autentikasi
Sekarang kita akan membuat middleware untuk memverifikasi sesi yang ada di setiap permintaan HTTP. Pada tahap ini, kita memerlukan:
Store
dari gorilla/sessions yang akan digunakan untuk menyimpan sesi di memori.- Fungsi middleware untuk memeriksa apakah sesi yang sah tersedia.
Kode Program authMiddleware.go
package main
import (
"github.com/gorilla/sessions"
"github.com/julienschmidt/httprouter"
"net/http"
"log"
)
var store = sessions.NewCookieStore([]byte("secret-key"))
// AuthMiddleware memeriksa apakah sesi pengguna valid
func AuthMiddleware(next httprouter.Handle) httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
// Mengambil session dari request
session, err := store.Get(r, "session-name")
if err != nil {
http.Error(w, "Could not get session", http.StatusInternalServerError)
return
}
// Mengecek apakah sesi "user" ada
user, ok := session.Values["user"]
if !ok || user == nil {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
// Melanjutkan permintaan jika sudah terautentikasi
next(w, r, ps)
}
}
func main() {
// Membuat router dan route
router := httprouter.New()
router.GET("/private", AuthMiddleware(privatePage))
// Menjalankan server
log.Fatal(http.ListenAndServe(":8080", router))
}
// Handler untuk halaman private yang membutuhkan otentikasi
func privatePage(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
w.Write([]byte("Welcome to the private page"))
}
Penjelasan kode:
- store adalah objek
gorilla/sessions
yang digunakan untuk menyimpan sesi menggunakan cookie. - AuthMiddleware adalah middleware yang akan mengecek apakah sesi pengguna yang valid ada dalam cookie.
- Jika sesi valid, middleware akan meneruskan request ke handler berikutnya; jika tidak, akan mengirimkan respons dengan status 401 Unauthorized.
Langkah 4: Menyiapkan Endpoint Login untuk Menyimpan Sesi
Untuk menguji autentikasi, kita membutuhkan endpoint untuk login. Endpoint ini akan menginisialisasi sesi saat pengguna login berhasil.
Kode Program loginHandler.go
package main
import (
"github.com/julienschmidt/httprouter"
"net/http"
"log"
)
func loginHandler(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
// Mengambil sesi
session, _ := store.Get(r, "session-name")
// Set nilai sesi user (misalnya setelah login berhasil)
session.Values["user"] = "authenticated-user"
session.Save(r, w)
// Menampilkan pesan setelah login berhasil
w.Write([]byte("Login berhasil"))
}
func main() {
// Membuat router dan route
router := httprouter.New()
router.GET("/login", loginHandler)
router.GET("/private", AuthMiddleware(privatePage))
// Menjalankan server
log.Fatal(http.ListenAndServe(":8080", router))
}
Penjelasan:
- Saat pengguna mengunjungi endpoint
/login
, sesi untuk pengguna akan diset dengan nilai"user"
. - Dengan begitu, sesi ini dapat digunakan untuk memvalidasi permintaan selanjutnya di endpoint yang dilindungi (
/private
).
Langkah 5: Menulis Unit Test untuk Middleware
Membuat unit test adalah bagian penting untuk memastikan middleware berfungsi dengan baik. Di sini, kita akan menggunakan paket testing standar dari Golang untuk menulis unit test.
Kode Program authMiddleware_test.go
package main
import (
"github.com/julienschmidt/httprouter"
"net/http"
"net/http/httptest"
"testing"
)
func TestAuthMiddleware(t *testing.T) {
// Membuat router dan route untuk tes
router := httprouter.New()
router.GET("/private", AuthMiddleware(privatePage))
// Membuat request HTTP yang tidak diautentikasi
req, err := http.NewRequest("GET", "/private", nil)
if err != nil {
t.Fatal(err)
}
// Membangun ResponseRecorder untuk menangkap response
rr := httptest.NewRecorder()
router.ServeHTTP(rr, req)
// Memeriksa apakah response adalah Unauthorized (401)
if status := rr.Code; status != http.StatusUnauthorized {
t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusUnauthorized)
}
}
func TestLogin(t *testing.T) {
// Membuat router dan route untuk tes login
router := httprouter.New()
router.GET("/login", loginHandler)
// Membuat request HTTP untuk login
req, err := http.NewRequest("GET", "/login", nil)
if err != nil {
t.Fatal(err)
}
// Membangun ResponseRecorder
rr := httptest.NewRecorder()
router.ServeHTTP(rr, req)
// Memeriksa apakah response berhasil login
if rr.Code != http.StatusOK {
t.Errorf("Expected status OK, got %v", rr.Code)
}
}
Penjelasan Unit Test:
- TestAuthMiddleware: Menguji apakah middleware mengembalikan status 401 Unauthorized jika sesi pengguna tidak valid.
- TestLogin: Menguji apakah request login berhasil dengan status 200 OK.
Langkah 6: Kesimpulan
Dengan menggunakan Golang, kita dapat membuat middleware untuk Session-based Authentication secara efisien menggunakan httprouter. Dalam contoh ini, kita menyiapkan middleware yang memverifikasi keberadaan sesi pengguna dalam cookie untuk mengamankan endpoint.
Untuk informasi lebih lanjut mengenai Golang dan HTTP router, Anda dapat mengunjungi:
Ini adalah dasar dari bagaimana sistem autentikasi berbasis sesi dapat diimplementasikan di Golang menggunakan middleware. Jangan ragu untuk menggali lebih dalam tentang teknik-teknik dan implementasi lainnya!