gobuffalo / buffalo

Rapid Web Development w/ Go
http://gobuffalo.io
MIT License
8.08k stars 577 forks source link

[Question] Request lost headers #1890

Closed badstorm closed 4 years ago

badstorm commented 4 years ago

I have a very strage problem and I'm not sure if this is a bug or how the http request package is supposed to work.

I have a c# client that call a Buffalo Rest API Server that as two methods. For each call the c# client add an Authorization header with a Token. In Buffalo I check the token in this way:

func GetTokenFromRequest(c buffalo.Context) string {
   if authToken := c.Request().Header.Get("Authorization"); len(authToken) > 0 {
       return strings.TrimSpace(strings.Replace(authToken, "Token ", "", -1))
   }
   return ""
}

The problem is that when the client call the first method the request header contains those keys: Accept, Accept-Encoding, Accept-Language, Authorizaton, Connection , User-Agent

But when the client call the second method the only header key that was in the request is Connection and so fail the authorization.

I tried to build the same buffalo server in python and it works.

The two methods are, for testing, very easy: one is GET and one if POST and they returno a simple JSON.

func SimpleAPIGet(c buffalo.Context) error {
   token := helpers.GetTokenFromRequest(c)
   if (len(token) > = 0) {
     return c.Render(403, r.JSON("{"error":"No Token"}"))
   }  else {
     return c.Render(200, r.JSON("{"status":0}"))
   }
}

func SimpleAPIPost(c buffalo.Context) error {
   token := helpers.GetTokenFromRequest(c)
   if (len(token) > = 0) {
     return c.Render(403, r.JSON("{"error":"No Token"}"))
   }  else {
     return c.Render(200, r.JSON("{"status":0}"))
   }
}

Someone have some ideas?

badstorm commented 4 years ago

for anyone with the same problem: Using the WebClient (C#) the Authorization token is sent only if the response fail with code 401 and the header WWW-Authenticate. So I update my code in this way:

func SimpleAPIGet(c buffalo.Context) error {
   token := helpers.GetTokenFromRequest(c)

   c.Response().Header().Set("WWW-Authenticate", "Basic")

   if (len(token) > = 0) {
     return c.Render(**401**, r.JSON("{"error":"No Token"}"))
   }  else {
     return c.Render(200, r.JSON("{"status":0}"))
   }
}

func SimpleAPIPost(c buffalo.Context) error {
   token := helpers.GetTokenFromRequest(c)

   c.Response().Header().Set("WWW-Authenticate", "Basic")

   if (len(token) > = 0) {
     return c.Render(**401**, r.JSON("{"error":"No Token"}"))
   }  else {
     return c.Render(200, r.JSON("{"status":0}"))
   }
}

In python works because using the Django framework everything is automated.