Gofiber
  • Basic backend dengan Gofiber part 1
    • Pengenalan Gofiber
    • Instalasi Gofiber
    • Auto reload dengan air
    • Membaca semua data di struct dengan Gofiber
    • Membaca data spesifik di struct dengan Gofiber
    • Membuat data di struct dengan Gofiber
    • Mengupdate data di struct dengan Gofiber
    • Menghapus data di struct dengan Gofiber
    • Implementasi MVC di Gofiber
  • Basic backend dengan Gofiber part 2
    • Setting database menggunahkan gorm.io di Gofiber
    • Menambahkan query ke database di Gofiber
    • Membuat relasi dengan gorm di Gofiber
    • Membuat validasi dengan validator di Gofiber
    • Membuat CORS di Gofiber
    • Menghandle serangan XSS(Cross-Site Scripting) di Gofiber
    • Mengamankan header HTTP dengan helmet di Gofiber
    • Membuat middleware menggunahkan JWT(JSON Web Token) di Gofiber
    • Menambahkan query search di Gofiber
    • Menambahkan query sort di Gofiber
    • Membuat pagination di Gofiber
    • Membuat refresh token di Gofiber
    • Membuat local upload file di Gofiber
    • Membuat server upload dengan cloudinary di Gofiber
    • Membuat analisis code dengan GolangCI-Lint di Gofiber
Powered by GitBook
On this page
  1. Basic backend dengan Gofiber part 2

Membuat refresh token di Gofiber

Langkah-langkah Implementasi Refresh Token

  1. Update Helper JWT untuk Mendukung Refresh Token:

    • Tambahkan fungsi GenerateRefreshToken untuk menghasilkan refresh token dengan klaim yang sama namun waktu kedaluwarsa yang lebih lama.

    // src/helpers/jwt.go
    
    package helpers
    
    import (
        "time"
    
        "github.com/dgrijalva/jwt-go"
    )
    
    // GenerateToken generates a JWT token with dynamic claims
    func GenerateToken(secretKey string, payload map[string]interface{}) (string, error) {
        token := jwt.New(jwt.SigningMethodHS256)
        claims := token.Claims.(jwt.MapClaims)
    
        for key, value := range payload {
            claims[key] = value
        }
    
        claims["exp"] = time.Now().Add(time.Hour * 1).Unix()
    
        tokenString, err := token.SignedString([]byte(secretKey))
        if err != nil {
            return "", err
        }
    
        return tokenString, nil
    }
    
    // GenerateRefreshToken generates a refresh JWT token with dynamic claims
    func GenerateRefreshToken(secretKey string, payload map[string]interface{}) (string, error) {
        token := jwt.New(jwt.SigningMethodHS256)
        claims := token.Claims.(jwt.MapClaims)
    
        for key, value := range payload {
            claims[key] = value
        }
    
        claims["exp"] = time.Now().Add(time.Hour * 24).Unix()
    
        refreshTokenString, err := token.SignedString([]byte(secretKey))
        if err != nil {
            return "", err
        }
    
        return refreshTokenString, nil
    }
  2. Update Controller untuk Login dan Refresh Token:

    • Update fungsi LoginUser untuk mengembalikan access token dan refresh token.

    • Tambahkan fungsi RefreshToken untuk menghasilkan token baru berdasarkan refresh token yang valid.

    // 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)
    
        models.PostUser(&user)
    
        return c.Status(fiber.StatusCreated).JSON(fiber.Map{
            "message": "Register successfully",
        })
    }
    
    func LoginUser(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",
            })
        }
    
        validateEmail := models.FindEmail(&user)
        if len(validateEmail) == 0 {
            return c.Status(fiber.StatusNotFound).JSON(fiber.Map{
                "message": "Email not found",
            })
        }
    
        var PasswordSecond string
        for _, user := range validateEmail {
            PasswordSecond = user.Password
        }
    
        if err := bcrypt.CompareHashAndPassword([]byte(PasswordSecond), []byte(user.Password)); err != nil || user.Password == "" {
            return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
                "message": "Invalid password",
            })
        }
    
        jwtKey := os.Getenv("SECRETKEY")
        payload := map[string]interface{}{
            "email": user.Email,
        }
    
        token, err := helpers.GenerateToken(jwtKey, payload)
        if err != nil {
            return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
                "error": "Could not generate access token",
            })
        }
    
        refreshToken, err := helpers.GenerateRefreshToken(jwtKey, payload)
        if err != nil {
            return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
                "error": "Could not generate refresh token",
            })
        }
    
        item := map[string]string{
            "Email":        user.Email,
            "Token":        token,
            "RefreshToken": refreshToken,
        }
    
        return c.Status(fiber.StatusCreated).JSON(fiber.Map{
            "message": "Login successfully",
            "data":    item,
        })
    }
    
    func RefreshToken(c *fiber.Ctx) error {
        var input struct {
            RefreshToken string `json:"refreshToken"`
        }
        if err := c.BodyParser(&input); err != nil {
            return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
                "error": "Failed to parse request body",
            })
        }
    
        jwtKey := os.Getenv("SECRETKEY")
        token, err := helpers.GenerateToken(jwtKey, map[string]interface{}{"refreshToken": input.RefreshToken})
        if err != nil {
            return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
                "error": "Could not generate access token",
            })
        }
    
        refreshToken, err := helpers.GenerateRefreshToken(jwtKey, map[string]interface{}{"refreshToken": input.RefreshToken})
        if err != nil {
            return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
                "error": "Could not generate refresh token",
            })
        }
        item := map[string]string{
            "Token":        token,
            "RefreshToken": refreshToken,
        }
    
        return c.Status(fiber.StatusCreated).JSON(fiber.Map{
            "message": "Refresh successfully",
            "data":    item,
        })
    }
  3. Update Routes untuk Mendukung Refresh Token:

    • Tambahkan route baru untuk refreshToken di file routes.

    // 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)
        app.Post("/refreshToken", controllers.RefreshToken)
    }

Dengan langkah-langkah ini, Anda telah berhasil mengimplementasikan fitur refresh token dalam aplikasi. Refresh token memungkinkan pengguna untuk mendapatkan token baru tanpa perlu login ulang ketika token akses mereka kedaluwarsa.

PreviousMembuat pagination di GofiberNextMembuat local upload file di Gofiber

Last updated 1 year ago

GitHub - zakimaliki/basic_gofiber_part_1 at 0cdf52d112388cee51fc6f21556e511a5ade7449GitHub
Logo