pemrograman

15 Membuat Middleware Session Based Authentication Pada Golang

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:

  1. Buat direktori proyek di terminal atau melalui IDE favorit Anda.
  2. 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:

  1. Store dari gorilla/sessions yang akan digunakan untuk menyimpan sesi di memori.
  2. 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:

  1. store adalah objek gorilla/sessions yang digunakan untuk menyimpan sesi menggunakan cookie.
  2. AuthMiddleware adalah middleware yang akan mengecek apakah sesi pengguna yang valid ada dalam cookie.
  3. 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:

  1. TestAuthMiddleware: Menguji apakah middleware mengembalikan status 401 Unauthorized jika sesi pengguna tidak valid.
  2. 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!

comments powered by Disqus