Cara menggunakan mongodb jwt authentication

JWT merupakan salah satu standar JSON (RFC 7519) untuk keperluan akses token. Token dibentuk dari kombinasi beberapa informasi yang di-encode dan di-enkripsi. Informasi yang dimaksud adalah header, payload, dan signature.

Contoh JWT:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Skema JWT:

[email protected]", "group": "admin" }, { "username": "farhan", "password": "masokpakeko", "email": "[email protected]", "group": "publisher" }] 0. Berikut merupakan spesifikasi aplikasinya:

  • Pengaksesan package main import "net/http" type CustomMux struct { http.ServeMux middlewares []func(next http.Handler) http.Handler } func (c *CustomMux) RegisterMiddleware(next func(next http.Handler) http.Handler) { c.middlewares = append(c.middlewares, next) } func (c *CustomMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { var current http.Handler = &c.ServeMux for _, next := range c.middlewares { current = next(current) } current.ServeHTTP(w, r) } 9 memerlukan token JWT.
  • Token didapat dari proses otentikasi ke endpoint [{ "username": "noval", "password": "kaliparejaya123", "email": "[email protected]", "group": "admin" }, { "username": "farhan", "password": "masokpakeko", "email": "[email protected]", "group": "publisher" }] 0 dengan menyisipkan username dan password.
  • Pada aplikasi yang sudah kita buat, sudah ada data list user yang tersimpan di database (sebenarnya bukan di-database, tapi di file json).

Ok, sekarang siapkan folder project baru.

• File [{ "username": "noval", "password": "kaliparejaya123", "email": "[email protected]", "group": "admin" }, { "username": "farhan", "password": "masokpakeko", "email": "[email protected]", "group": "publisher" }] 3

Lanjut isi file [{ "username": "noval", "password": "kaliparejaya123", "email": "[email protected]", "group": "admin" }, { "username": "farhan", "password": "masokpakeko", "email": "[email protected]", "group": "publisher" }] 3 dengan kode middleware yang sudah biasa kita gunakan.

package main import "net/http" type CustomMux struct { http.ServeMux middlewares []func(next http.Handler) http.Handler } func (c *CustomMux) RegisterMiddleware(next func(next http.Handler) http.Handler) { c.middlewares = append(c.middlewares, next) } func (c *CustomMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { var current http.Handler = &c.ServeMux for _, next := range c.middlewares { current = next(current) } current.ServeHTTP(w, r) }

• File [{ "username": "noval", "password": "kaliparejaya123", "email": "[email protected]", "group": "admin" }, { "username": "farhan", "password": "masokpakeko", "email": "[email protected]", "group": "publisher" }] 5

Juga isi file [{ "username": "noval", "password": "kaliparejaya123", "email": "[email protected]", "group": "admin" }, { "username": "farhan", "password": "masokpakeko", "email": "[email protected]", "group": "publisher" }] 5 yang merupakan database aplikasi. Silakan tambahkan data JSON berikut.

[{ "username": "noval", "password": "kaliparejaya123", "email": "[email protected]", "group": "admin" }, { "username": "farhan", "password": "masokpakeko", "email": "[email protected]", "group": "publisher" }]

• File [{ "username": "noval", "password": "kaliparejaya123", "email": "[email protected]", "group": "admin" }, { "username": "farhan", "password": "masokpakeko", "email": "[email protected]", "group": "publisher" }] 7

Sekarang kita fokus ke file [{ "username": "noval", "password": "kaliparejaya123", "email": "[email protected]", "group": "admin" }, { "username": "farhan", "password": "masokpakeko", "email": "[email protected]", "group": "publisher" }] 7. Import packages yang diperlukan. Salah satu dari packages tersebut adalah golang-jwt/jwt, yang digunakan untuk keperluan JWT.

go get -u github.com/golang-jwt/jwt/[email protected] go get -u github.com/novalagung/gubrak/v2 package main import ( "context" "encoding/json" "fmt" "io/ioutil" "net/http" "os" "path/filepath" "strings" jwt "github.com/golang-jwt/jwt/v4" gubrak "github.com/novalagung/gubrak/v2" )

Masih di file yang sama, siapkan 4 buah konstanta yaitu: nama aplikasi, durasi login, metode enkripsi token, dan secret key.

type M map[string]interface{} var APPLICATION_NAME = "My Simple JWT App" var LOGIN_EXPIRATION_DURATION = time.Duration(1) * time.Hour var JWT_SIGNING_METHOD = jwt.SigningMethodHS256 var JWT_SIGNATURE_KEY = []byte("the secret of kalimdor")

Kemudian buat fungsi [{ "username": "noval", "password": "kaliparejaya123", "email": "[email protected]", "group": "admin" }, { "username": "farhan", "password": "masokpakeko", "email": "[email protected]", "group": "publisher" }] 9, siapkan didalmnya sebuah go get -u github.com/golang-jwt/jwt/[email protected] go get -u github.com/novalagung/gubrak/v2 0 baru, dan daftarkan middleware go get -u github.com/golang-jwt/jwt/[email protected] go get -u github.com/novalagung/gubrak/v2 1 dan dua buah rute package main import "net/http" type CustomMux struct { http.ServeMux middlewares []func(next http.Handler) http.Handler } func (c *CustomMux) RegisterMiddleware(next func(next http.Handler) http.Handler) { c.middlewares = append(c.middlewares, next) } func (c *CustomMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { var current http.Handler = &c.ServeMux for _, next := range c.middlewares { current = next(current) } current.ServeHTTP(w, r) } 9 dan [{ "username": "noval", "password": "kaliparejaya123", "email": "[email protected]", "group": "admin" }, { "username": "farhan", "password": "masokpakeko", "email": "[email protected]", "group": "publisher" }] 0.

func main() { mux := new(CustomMux) mux.RegisterMiddleware(MiddlewareJWTAuthorization) mux.HandleFunc("/login", HandlerLogin) mux.HandleFunc("/index", HandlerIndex) server := new(http.Server) server.Handler = mux server.Addr = ":8080" fmt.Println("Starting server at", server.Addr) server.ListenAndServe() }

Middleware go get -u github.com/golang-jwt/jwt/[email protected] go get -u github.com/novalagung/gubrak/v2 1 nantinya akan kita buat, tugasnya memvalidasi setiap request yang masuk, dengan cara mengecek token JWT yang disertakan. Middleware ini hanya berguna pada request ke selain endpoint [{ "username": "noval", "password": "kaliparejaya123", "email": "[email protected]", "group": "admin" }, { "username": "farhan", "password": "masokpakeko", "email": "[email protected]", "group": "publisher" }] 0, karena pada endpoint tersebut proses otentikasi terjadi.

C.32.3. Otentikasi & Generate Token

Siapkan handler go get -u github.com/golang-jwt/jwt/[email protected] go get -u github.com/novalagung/gubrak/v2 6. Tulis kode berikut.

Handler ini bertugas untuk meng-otentikasi client/consumer. Data username dan password dikirimkan ke endpoint dalam bentuk B.18. HTTP Basic Auth. Data tersebut kemudian disisipkan dalam pemanggilan fungsi otentikasi go get -u github.com/golang-jwt/jwt/[email protected] go get -u github.com/novalagung/gubrak/v2 7, yang nantinya juga akan kita buat.

ok, userInfo := authenticateUser(username, password) if !ok { http.Error(w, "Invalid username or password", http.StatusBadRequest) return }

Fungsi go get -u github.com/golang-jwt/jwt/[email protected] go get -u github.com/novalagung/gubrak/v2 7 memiliki dua nilai balik yang ditampung oleh variabel berikut:

  • Variabel go get -u github.com/golang-jwt/jwt/[email protected] go get -u github.com/novalagung/gubrak/v2 9, penanda sukses tidaknya otentikasi.
  • Variabel package main import ( "context" "encoding/json" "fmt" "io/ioutil" "net/http" "os" "path/filepath" "strings" jwt "github.com/golang-jwt/jwt/v4" gubrak "github.com/novalagung/gubrak/v2" ) 0, isinya informasi user yang sedang login, datanya didapat dari package main import ( "context" "encoding/json" "fmt" "io/ioutil" "net/http" "os" "path/filepath" "strings" jwt "github.com/golang-jwt/jwt/v4" gubrak "github.com/novalagung/gubrak/v2" ) 1 (tetapi tanpa password).

Selanjutnya kita akan buat objek claims. Objek ini harus memenuhi persyaratan interface package main import ( "context" "encoding/json" "fmt" "io/ioutil" "net/http" "os" "path/filepath" "strings" jwt "github.com/golang-jwt/jwt/v4" gubrak "github.com/novalagung/gubrak/v2" ) 2. Objek claims bisa dibuat dari tipe package main import ( "context" "encoding/json" "fmt" "io/ioutil" "net/http" "os" "path/filepath" "strings" jwt "github.com/golang-jwt/jwt/v4" gubrak "github.com/novalagung/gubrak/v2" ) 3 dengan cara membungkusnya dalam fungsi package main import ( "context" "encoding/json" "fmt" "io/ioutil" "net/http" "os" "path/filepath" "strings" jwt "github.com/golang-jwt/jwt/v4" gubrak "github.com/novalagung/gubrak/v2" ) 4; atau dengan meng-embed interface package main import ( "context" "encoding/json" "fmt" "io/ioutil" "net/http" "os" "path/filepath" "strings" jwt "github.com/golang-jwt/jwt/v4" gubrak "github.com/novalagung/gubrak/v2" ) 5 pada struct baru, dan cara inilah yang akan kita pakai.

Seperti yang sudah kita bahas di awal, bahwa claims isinya adalah data-data untuk keperluan otentikasi. Dalam prakteknya, claims merupakan sebuah objek yang memilik banyak property atau fields. Nah, objek claims harus memiliki fields yang termasuk di dalam list . Dengan meng-embed interface package main import ( "context" "encoding/json" "fmt" "io/ioutil" "net/http" "os" "path/filepath" "strings" jwt "github.com/golang-jwt/jwt/v4" gubrak "github.com/novalagung/gubrak/v2" ) 5, maka fields pada struct dianggap sudah terwakili.

Pada aplikasi yang sedang kita kembangkan, claims selain menampung standard fields, juga menampung beberapa informasi lain, oleh karena itu kita perlu buat package main import ( "context" "encoding/json" "fmt" "io/ioutil" "net/http" "os" "path/filepath" "strings" jwt "github.com/golang-jwt/jwt/v4" gubrak "github.com/novalagung/gubrak/v2" ) 7 baru yang meng-embed package main import ( "context" "encoding/json" "fmt" "io/ioutil" "net/http" "os" "path/filepath" "strings" jwt "github.com/golang-jwt/jwt/v4" gubrak "github.com/novalagung/gubrak/v2" ) 5.

type MyClaims struct { jwt.StandardClaims Username string `json:"Username"` Email string `json:"Email"` Group string `json:"Group"` }

Ok, struct package main import ( "context" "encoding/json" "fmt" "io/ioutil" "net/http" "os" "path/filepath" "strings" jwt "github.com/golang-jwt/jwt/v4" gubrak "github.com/novalagung/gubrak/v2" ) 9 sudah siap, sekarang buat objek baru dari struct tersebut.

claims := MyClaims{ StandardClaims: jwt.StandardClaims{ Issuer: APPLICATION_NAME, ExpiresAt: time.Now().Add(LOGIN_EXPIRATION_DURATION).Unix(), }, Username: userInfo["username"].(string), Email: userInfo["email"].(string), Group: userInfo["group"].(string), }

Ada beberapa standard claims, pada contoh di atas hanya dua yang di-isi nilainya, type M map[string]interface{} var APPLICATION_NAME = "My Simple JWT App" var LOGIN_EXPIRATION_DURATION = time.Duration(1) * time.Hour var JWT_SIGNING_METHOD = jwt.SigningMethodHS256 var JWT_SIGNATURE_KEY = []byte("the secret of kalimdor") 0 dan type M map[string]interface{} var APPLICATION_NAME = "My Simple JWT App" var LOGIN_EXPIRATION_DURATION = time.Duration(1) * time.Hour var JWT_SIGNING_METHOD = jwt.SigningMethodHS256 var JWT_SIGNATURE_KEY = []byte("the secret of kalimdor") 1, selebihnya kita kosongi. Lalu 3 fields tambahan yang kita buat (username, email, dan group) di-isi menggunakan data yang didapat dari package main import ( "context" "encoding/json" "fmt" "io/ioutil" "net/http" "os" "path/filepath" "strings" jwt "github.com/golang-jwt/jwt/v4" gubrak "github.com/novalagung/gubrak/v2" ) 0.

  • type M map[string]interface{} var APPLICATION_NAME = "My Simple JWT App" var LOGIN_EXPIRATION_DURATION = time.Duration(1) * time.Hour var JWT_SIGNING_METHOD = jwt.SigningMethodHS256 var JWT_SIGNATURE_KEY = []byte("the secret of kalimdor") 0 (code type M map[string]interface{} var APPLICATION_NAME = "My Simple JWT App" var LOGIN_EXPIRATION_DURATION = time.Duration(1) * time.Hour var JWT_SIGNING_METHOD = jwt.SigningMethodHS256 var JWT_SIGNATURE_KEY = []byte("the secret of kalimdor") 4), adalah penerbit JWT, dalam konteks ini adalah type M map[string]interface{} var APPLICATION_NAME = "My Simple JWT App" var LOGIN_EXPIRATION_DURATION = time.Duration(1) * time.Hour var JWT_SIGNING_METHOD = jwt.SigningMethodHS256 var JWT_SIGNATURE_KEY = []byte("the secret of kalimdor") 5.
  • type M map[string]interface{} var APPLICATION_NAME = "My Simple JWT App" var LOGIN_EXPIRATION_DURATION = time.Duration(1) * time.Hour var JWT_SIGNING_METHOD = jwt.SigningMethodHS256 var JWT_SIGNATURE_KEY = []byte("the secret of kalimdor") 1 (code type M map[string]interface{} var APPLICATION_NAME = "My Simple JWT App" var LOGIN_EXPIRATION_DURATION = time.Duration(1) * time.Hour var JWT_SIGNING_METHOD = jwt.SigningMethodHS256 var JWT_SIGNATURE_KEY = []byte("the secret of kalimdor") 7), adalah kapan token JWT dianggap expired.

Ok, objek claims sudah siap, sekarang buat token baru. Pembuatannya dilakukan menggunakan fungsi type M map[string]interface{} var APPLICATION_NAME = "My Simple JWT App" var LOGIN_EXPIRATION_DURATION = time.Duration(1) * time.Hour var JWT_SIGNING_METHOD = jwt.SigningMethodHS256 var JWT_SIGNATURE_KEY = []byte("the secret of kalimdor") 8 yang menghasilkan nilai balik bertipe type M map[string]interface{} var APPLICATION_NAME = "My Simple JWT App" var LOGIN_EXPIRATION_DURATION = time.Duration(1) * time.Hour var JWT_SIGNING_METHOD = jwt.SigningMethodHS256 var JWT_SIGNATURE_KEY = []byte("the secret of kalimdor") 9. Parameter pertama adalah metode enkripsi yang digunakan, yaitu func main() { mux := new(CustomMux) mux.RegisterMiddleware(MiddlewareJWTAuthorization) mux.HandleFunc("/login", HandlerLogin) mux.HandleFunc("/index", HandlerIndex) server := new(http.Server) server.Handler = mux server.Addr = ":8080" fmt.Println("Starting server at", server.Addr) server.ListenAndServe() } 0, dan parameter kedua adalah func main() { mux := new(CustomMux) mux.RegisterMiddleware(MiddlewareJWTAuthorization) mux.HandleFunc("/login", HandlerLogin) mux.HandleFunc("/index", HandlerIndex) server := new(http.Server) server.Handler = mux server.Addr = ":8080" fmt.Println("Starting server at", server.Addr) server.ListenAndServe() } 1.

package main import "net/http" type CustomMux struct { http.ServeMux middlewares []func(next http.Handler) http.Handler } func (c *CustomMux) RegisterMiddleware(next func(next http.Handler) http.Handler) { c.middlewares = append(c.middlewares, next) } func (c *CustomMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { var current http.Handler = &c.ServeMux for _, next := range c.middlewares { current = next(current) } current.ServeHTTP(w, r) } 0

Kemudian tanda-tangani token tersebut menggunakan secret key yang sudah didefinisikan di func main() { mux := new(CustomMux) mux.RegisterMiddleware(MiddlewareJWTAuthorization) mux.HandleFunc("/login", HandlerLogin) mux.HandleFunc("/index", HandlerIndex) server := new(http.Server) server.Handler = mux server.Addr = ":8080" fmt.Println("Starting server at", server.Addr) server.ListenAndServe() } 2, caranya dengan memanggil method func main() { mux := new(CustomMux) mux.RegisterMiddleware(MiddlewareJWTAuthorization) mux.HandleFunc("/login", HandlerLogin) mux.HandleFunc("/index", HandlerIndex) server := new(http.Server) server.Handler = mux server.Addr = ":8080" fmt.Println("Starting server at", server.Addr) server.ListenAndServe() } 3 milik objek type M map[string]interface{} var APPLICATION_NAME = "My Simple JWT App" var LOGIN_EXPIRATION_DURATION = time.Duration(1) * time.Hour var JWT_SIGNING_METHOD = jwt.SigningMethodHS256 var JWT_SIGNATURE_KEY = []byte("the secret of kalimdor") 9. Pemanggilan method ini mengembalikan data token string yang kemudian dijadikan nilai balik handler. Token string inilah yang dibutuhkan client/consumer untuk bisa mengakses endpoints yang ada.

package main import "net/http" type CustomMux struct { http.ServeMux middlewares []func(next http.Handler) http.Handler } func (c *CustomMux) RegisterMiddleware(next func(next http.Handler) http.Handler) { c.middlewares = append(c.middlewares, next) } func (c *CustomMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { var current http.Handler = &c.ServeMux for _, next := range c.middlewares { current = next(current) } current.ServeHTTP(w, r) } 1

Bagian otentikasi dan generate token sebenarnya cukup sampai di sini. Tapi sebenarnya ada yang kurang, yaitu fungsi go get -u github.com/golang-jwt/jwt/[email protected] go get -u github.com/novalagung/gubrak/v2 7. Silakan buat fungsi tersebut.

package main import "net/http" type CustomMux struct { http.ServeMux middlewares []func(next http.Handler) http.Handler } func (c *CustomMux) RegisterMiddleware(next func(next http.Handler) http.Handler) { c.middlewares = append(c.middlewares, next) } func (c *CustomMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { var current http.Handler = &c.ServeMux for _, next := range c.middlewares { current = next(current) } current.ServeHTTP(w, r) } 2

Isi fungsi go get -u github.com/golang-jwt/jwt/[email protected] go get -u github.com/novalagung/gubrak/v2 7 cukup jelas, sesuai namanya, yaitu melakukan pencocokan username dan password dengan data yang ada di dalam file [{ "username": "noval", "password": "kaliparejaya123", "email": "[email protected]", "group": "admin" }, { "username": "farhan", "password": "masokpakeko", "email": "[email protected]", "group": "publisher" }] 5.

Sekarang kita perlu menyiapkan go get -u github.com/golang-jwt/jwt/[email protected] go get -u github.com/novalagung/gubrak/v2 1, yang tugasnya adalah mengecek setiap request yang masuk ke endpoint selain [{ "username": "noval", "password": "kaliparejaya123", "email": "[email protected]", "group": "admin" }, { "username": "farhan", "password": "masokpakeko", "email": "[email protected]", "group": "publisher" }] 0, apakah ada akses token yang dibawa atau tidak. Dan jika ada, akan diverifikasi valid tidaknya token tersebut.

Kita gunakan skema header ok, userInfo := authenticateUser(username, password) if !ok { http.Error(w, "Invalid username or password", http.StatusBadRequest) return } 0, sesuai spesifikasi RFC 6750 untuk keperluan penempatan dan pengambilan token.

Token di-extract dari header, kemudian diparsing dan di-validasi menggunakan fungsi ok, userInfo := authenticateUser(username, password) if !ok { http.Error(w, "Invalid username or password", http.StatusBadRequest) return } 1.

package main import "net/http" type CustomMux struct { http.ServeMux middlewares []func(next http.Handler) http.Handler } func (c *CustomMux) RegisterMiddleware(next func(next http.Handler) http.Handler) { c.middlewares = append(c.middlewares, next) } func (c *CustomMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { var current http.Handler = &c.ServeMux for _, next := range c.middlewares { current = next(current) } current.ServeHTTP(w, r) } 3

Parameter ke-2 fungsi ok, userInfo := authenticateUser(username, password) if !ok { http.Error(w, "Invalid username or password", http.StatusBadRequest) return } 1 berisikan callback untuk pengecekan valid tidak-nya signing method, jika valid maka secret key dikembalikan. Fungsi ok, userInfo := authenticateUser(username, password) if !ok { http.Error(w, "Invalid username or password", http.StatusBadRequest) return } 1 ini sendiri mengembalikan objek token.

Dari objek token, informasi claims diambil, lalu dilakukan pengecekan valid-tidaknya claims tersebut.

package main import "net/http" type CustomMux struct { http.ServeMux middlewares []func(next http.Handler) http.Handler } func (c *CustomMux) RegisterMiddleware(next func(next http.Handler) http.Handler) { c.middlewares = append(c.middlewares, next) } func (c *CustomMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { var current http.Handler = &c.ServeMux for _, next := range c.middlewares { current = next(current) } current.ServeHTTP(w, r) } 4

O iya, mungkin ada pertanyaan kenapa objek claims yang dihasilkan ok, userInfo := authenticateUser(username, password) if !ok { http.Error(w, "Invalid username or password", http.StatusBadRequest) return } 1 tipenya bukan package main import ( "context" "encoding/json" "fmt" "io/ioutil" "net/http" "os" "path/filepath" "strings" jwt "github.com/golang-jwt/jwt/v4" gubrak "github.com/novalagung/gubrak/v2" ) 9. Hal ini karena setelah objek claims dimasukan dalam proses pembentukan token, lewat fungsi type M map[string]interface{} var APPLICATION_NAME = "My Simple JWT App" var LOGIN_EXPIRATION_DURATION = time.Duration(1) * time.Hour var JWT_SIGNING_METHOD = jwt.SigningMethodHS256 var JWT_SIGNATURE_KEY = []byte("the secret of kalimdor") 8, objek akan di-encode ke tipe ok, userInfo := authenticateUser(username, password) if !ok { http.Error(w, "Invalid username or password", http.StatusBadRequest) return } 7.

Data claims yang didapat disisipkan ke dalam context, agar nantinya di endpoint, informasi package main import ( "context" "encoding/json" "fmt" "io/ioutil" "net/http" "os" "path/filepath" "strings" jwt "github.com/golang-jwt/jwt/v4" gubrak "github.com/novalagung/gubrak/v2" ) 0 bisa diambil dengan mudah dari context request.

package main import "net/http" type CustomMux struct { http.ServeMux middlewares []func(next http.Handler) http.Handler } func (c *CustomMux) RegisterMiddleware(next func(next http.Handler) http.Handler) { c.middlewares = append(c.middlewares, next) } func (c *CustomMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { var current http.Handler = &c.ServeMux for _, next := range c.middlewares { current = next(current) } current.ServeHTTP(w, r) } 5

• Handler Index

Terakhir, kita perlu menyiapkan handler untuk rute package main import "net/http" type CustomMux struct { http.ServeMux middlewares []func(next http.Handler) http.Handler } func (c *CustomMux) RegisterMiddleware(next func(next http.Handler) http.Handler) { c.middlewares = append(c.middlewares, next) } func (c *CustomMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { var current http.Handler = &c.ServeMux for _, next := range c.middlewares { current = next(current) } current.ServeHTTP(w, r) } 9.

package main import "net/http" type CustomMux struct { http.ServeMux middlewares []func(next http.Handler) http.Handler } func (c *CustomMux) RegisterMiddleware(next func(next http.Handler) http.Handler) { c.middlewares = append(c.middlewares, next) } func (c *CustomMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { var current http.Handler = &c.ServeMux for _, next := range c.middlewares { current = next(current) } current.ServeHTTP(w, r) } 6

Informasi package main import ( "context" "encoding/json" "fmt" "io/ioutil" "net/http" "os" "path/filepath" "strings" jwt "github.com/golang-jwt/jwt/v4" gubrak "github.com/novalagung/gubrak/v2" ) 0 diambil dari context, lalu ditampilkan sebagai response endpoint.

C.32.5. Testing

Jalankan aplikasi, lalu test menggunakan curl.

• Otentikasi

package main import "net/http" type CustomMux struct { http.ServeMux middlewares []func(next http.Handler) http.Handler } func (c *CustomMux) RegisterMiddleware(next func(next http.Handler) http.Handler) { c.middlewares = append(c.middlewares, next) } func (c *CustomMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { var current http.Handler = &c.ServeMux for _, next := range c.middlewares { current = next(current) } current.ServeHTTP(w, r) } 7

Output:

• Mengakses Endpoint

Test endpoint package main import "net/http" type CustomMux struct { http.ServeMux middlewares []func(next http.Handler) http.Handler } func (c *CustomMux) RegisterMiddleware(next func(next http.Handler) http.Handler) { c.middlewares = append(c.middlewares, next) } func (c *CustomMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { var current http.Handler = &c.ServeMux for _, next := range c.middlewares { current = next(current) } current.ServeHTTP(w, r) } 9. Sisipkan token yang dikembalikan pada saat otentikasi, sebagai value header otorisasi dengan skema ok, userInfo := authenticateUser(username, password) if !ok { http.Error(w, "Invalid username or password", http.StatusBadRequest) return } 0.

package main import "net/http" type CustomMux struct { http.ServeMux middlewares []func(next http.Handler) http.Handler } func (c *CustomMux) RegisterMiddleware(next func(next http.Handler) http.Handler) { c.middlewares = append(c.middlewares, next) } func (c *CustomMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { var current http.Handler = &c.ServeMux for _, next := range c.middlewares { current = next(current) } current.ServeHTTP(w, r) } 8

Output:

Semua berjalan sesuai harapan. Agar lebih meyakinkan, coba lakukan beberapa test dengan skenario yg salah, seperti:

Postingan terbaru

LIHAT SEMUA