Membuat middleware menggunahkan JWT(JSON Web Token) di Gofiber
Konsep JWT (JSON Web Token)
JWT adalah metode yang digunakan untuk mengamankan komunikasi antara client dan server dengan cara membuat token yang berisi klaim-klaim tertentu, seperti user ID atau email. Token ini kemudian dikirim bersama setiap permintaan untuk memverifikasi identitas pengguna.
Langkah-langkah Menggunakan JWT dengan github.com/dgrijalva/jwt-go
github.com/dgrijalva/jwt-go
Install Package JWT: Jalankan perintah berikut untuk menginstall paket
jwt-go
:go get github.com/dgrijalva/jwt-go
Setup Environment Variables: Tambahkan variabel lingkungan untuk menyimpan kunci rahasia JWT. Buat file
.env
dan tambahkan:SECRETKEY=your_secret_key_here
Helper JWT: Buat helper untuk menghasilkan token JWT.
// src/helpers/jwt.go package helpers import ( "time" "github.com/dgrijalva/jwt-go" ) func GenerateToken(secretKey, email string) (string, error) { token := jwt.New(jwt.SigningMethodHS256) claims := token.Claims.(jwt.MapClaims) claims["email"] = email claims["exp"] = time.Now().Add(time.Hour * 1).Unix() return token.SignedString([]byte(secretKey)) }
Middleware JWT: Buat middleware untuk memeriksa validitas token JWT.
// src/middlewares/jwt.go package middlewares import ( "fmt" "os" "strings" "github.com/dgrijalva/jwt-go" "github.com/gofiber/fiber/v2" ) func ExtractToken(c *fiber.Ctx) string { bearerToken := c.Get("Authorization") if strings.HasPrefix(bearerToken, "Bearer ") { return strings.TrimPrefix(bearerToken, "Bearer ") } return "" } func JwtMiddleware() fiber.Handler { secretKey := os.Getenv("SECRETKEY") return func(c *fiber.Ctx) error { tokenString := ExtractToken(c) if tokenString == "" { return c.Status(fiber.StatusUnauthorized) .JSON(fiber.Map{"error": "Unauthorized"}) } _, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"]) } return []byte(secretKey), nil }) if err != nil { return c.Status(fiber.StatusUnauthorized) .JSON(fiber.Map{"error": "Unauthorized"}) } return c.Next() } }
Model User: Buat model untuk user.
// src/models/Users.go package models import ( "gofiber/src/configs" "gorm.io/gorm" ) type User struct { gorm.Model Email string `json:"email"` Password string `json:"password"` } func PostUser(user *User) error { return configs.DB.Create(user).Error } func FindEmail(email string) (*User, error) { var user User result := configs.DB.Where("email = ?", email).First(&user) return &user, result.Error }
Controller User: Buat controller untuk registrasi dan login user.
// src/controllers/UserController.go package controllers import ( "gofiber/src/helpers" "gofiber/src/models" "os" "github.com/gofiber/fiber/v2" "golang.org/x/crypto/bcrypt" ) func RegisterUser(c *fiber.Ctx) error { var user models.User if err := c.BodyParser(&user); err != nil { return c.Status(fiber.StatusBadRequest) .JSON(fiber.Map{"error": "Failed to parse request body"}) } hashPassword, _ := bcrypt.GenerateFromPassword([]byte(user.Password), bcrypt.DefaultCost) user.Password = string(hashPassword) if err := models.PostUser(&user); err != nil { return c.Status(fiber.StatusInternalServerError) .JSON(fiber.Map{"error": "Failed to create user"}) } return c.Status(fiber.StatusCreated) .JSON(fiber.Map{"message": "Register successfully"}) } func LoginUser(c *fiber.Ctx) error { var input models.User if err := c.BodyParser(&input); err != nil { return c.Status(fiber.StatusBadRequest) .JSON(fiber.Map{"error": "Failed to parse request body"}) } user, err := models.FindEmail(input.Email) if err != nil { return c.Status(fiber.StatusNotFound) .JSON(fiber.Map{"message": "Email not found"}) } if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(input.Password)); err != nil { return c.Status(fiber.StatusUnauthorized) .JSON(fiber.Map{"message": "Invalid password"}) } token, err := helpers.GenerateToken(os.Getenv("SECRETKEY"), user.Email) if err != nil { return c.Status(fiber.StatusInternalServerError) .JSON(fiber.Map{"error": "Failed to generate token"}) } return c.JSON(fiber.Map{"message": "Login successfully", "token": token}) }
Router: Tambahkan rute untuk registrasi dan login user.
// src/routes/main.go package routes import ( "gofiber/src/controllers" "gofiber/src/middlewares" "github.com/gofiber/fiber/v2" ) func Router(app *fiber.App) { // Product routes app.Get("/products", controllers.GetAllProducts) app.Get("/product/:id", controllers.GetProductById) app.Post("/product", controllers.CreateProduct) app.Put("/product/:id", controllers.UpdateProduct) app.Delete("/product/:id", controllers.DeleteProduct) // Category routes app.Get("/categories", middlewares.JwtMiddleware(), controllers.GetAllCategories) app.Get("/category/:id", controllers.GetCategoryById) app.Post("/category", controllers.CreateCategory) app.Put("/category/:id", controllers.UpdateCategory) app.Delete("/category/:id", controllers.DeleteCategory) // User routes app.Post("/register", controllers.RegisterUser) app.Post("/login", controllers.LoginUser) }
Migrasi Database: Tambahkan migrasi untuk model
User
.// src/helpers/migration.go package helpers import ( "gofiber/src/configs" "gofiber/src/models" ) func Migration() { configs.DB.AutoMigrate(&models.Product{}, &models.Category{}, &models.User{}) }
Dengan mengikuti langkah-langkah di atas, Anda dapat mengimplementasikan keamanan JWT untuk autentikasi dan menambahkan header keamanan menggunakan Helmet untuk meningkatkan keamanan aplikasi Fiber Anda.
Sumber : Dokumentasi
Last updated