2

I have the following code that works for JSON in the body of the POST request but i now want to convert this to using form-data in the body of the request

Here is what i have

func Signin(c *fiber.Ctx) error {
    var data map[string]string

    if err := c.BodyParser(&data); err != nil {
        return err
    }

    var user models.User

    findUser := database.DB.Where("email = ?", data.email).First(&user)

    token, err := middlewares.GenerateJWT(user.Email)

    if err != nil {
        c.Status(fiber.StatusBadRequest)
        return c.JSON(fiber.Map{
            "message": "Invalid credentials",
        })  
    }

    cookie := fiber.Cookie{
        Name: "access_token",
        Value: token,
        Expires: time.Now().Add(time.Hour * 24),
        HTTPOnly: true,
        Secure:   true,
    }

    c.Cookie(&cookie)

    return c.JSON(fiber.Map{
        "access_token": token,
        "token_type": "bearer",
    })

}

above works fine for raw JSON body but i want to change to form-data body

I have tried many things including this but to no avail

func Signin(c *fiber.Ctx) error {

    type SigninData struct {
        email  string `json:"email" xml:"email" form:"email"`
        password string `json:"password" xml:"password" form:"password"`
    }

    data := new(SigninData)

    if err := c.BodyParser(&data); err != nil {
        return err
    }

    var user models.User

    findUser := database.DB.Where("email = ?", data.email).First(&user)

    token, err := middlewares.GenerateJWT(user.Email)

    if err != nil {
        c.Status(fiber.StatusBadRequest)
        return c.JSON(fiber.Map{
            "message": "Invalid credentials",
        })  
    }


    cookie := fiber.Cookie{
        Name: "access_token",
        Value: token,
        Expires: time.Now().Add(time.Hour * 24),
        HTTPOnly: true,
        Secure:   true,
    }

    c.Cookie(&cookie)

    return c.JSON(fiber.Map{
        "access_token": token,
        "token_type": "bearer",
    })

}

but i get the following error

schema: interface must be a pointer to struct

what am i missing that i need to fix to get this to accept form-data?

uberrebu
  • 3,597
  • 9
  • 38
  • 73

1 Answers1

2

The method BodyParser expects a pointer to a struct as an argument, but your code is trying to pass it a pointer to a pointer to a struct. Please initialize the struct this way:

data := SigninData{}

Also, try to make the fields of the SigninData struct public:

type SigninData struct {
    Email  string `json:"email" xml:"email" form:"email"`
    Password string `json:"password" xml:"password" form:"password"`
}
Andrey Dyatlov
  • 1,628
  • 1
  • 10
  • 12
  • P.S i moved he struct inside the function | => so how do i get the value of the email? like this `data.email` because getting empty string from this `data.email` – uberrebu Dec 31 '21 at 05:44
  • @uberrebu, it doesn't matter where the struct is declared. Did you try both proposed changes? Did you make the fields of SigninData public by capitalizing their names? – Andrey Dyatlov Dec 31 '21 at 05:47
  • yeah i initialized the struct as mention but i also moved the SigninData inside the function, do i still to make it public? – uberrebu Dec 31 '21 at 05:48
  • I get this error when i use capitalization `data.email undefined (type SigninData has no field or method email, but does have Email)` – uberrebu Dec 31 '21 at 05:50
  • Please, capitalize it everywhere in the code. – Andrey Dyatlov Dec 31 '21 at 05:51
  • ok works now...any way to use the lowercase inside code? or it has to be capitalized? i thought this was supposed to help lowercase it? `json:"email" xml:"email" form:"email"` – uberrebu Dec 31 '21 at 05:56
  • I'm not sure why, but parsers like that work only with exported (public) fields. Tags allow you to use field names that differ from the ones in the document. – Andrey Dyatlov Dec 31 '21 at 06:17
  • gotcha...thanks a lot – uberrebu Dec 31 '21 at 06:19