0

I am trying to create a cookie in my client (127.0.0.1:3000) from an API made in Go (127.0.0.1:8080), I think I've added most headers in the response needed for CORS and the cookie has samesite=none and secure=true but it is still not being set. Below I've added a picture of the request and response as shown in the chrome devtools network tab and also code of axios where the request is made and code of go where the request is handled in the API server.

GO:

//Handles account sign ins
func Login(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
    fmt.Println("login handler")
    //decoder := json.NewDecoder(r.Body)
    //var t models.LoginUserData
    //err := decoder.Decode(&t)
    //if err != nil {
    //  log.Println(err)
    //}
    //middleware.SignIn(t.User.Username, t.User.Password)

    http.SetCookie(w, &http.Cookie{Name: "sabor", Value: "merda", Path: "/", HttpOnly: false, SameSite: http.SameSiteNoneMode, Secure: true, Domain: "127.0.0.1"})
    header := w.Header()
    header.Set("Access-Control-Allow-Credentials", "true")

    //header.Set("Access-Control-Expose-Headers", "Set-Cookie")
    header.Set("Access-Control-Allow-Headers", "Content-Type, withCredentials")
    header.Set("Access-Control-Allow-Origin", "http://127.0.0.1:3000")
    header.Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS")
    w.WriteHeader(http.StatusOK)
}

Axios:

let config = {
      headers: {
        withCredentials: true,
      },
    };

axios
      .post(
        "http://127.0.0.1:8080/login",

        {
          User: {
            Username: username,
            Password: password,
          },
        },

        config
      )
      .then(function (response) {
        console.log(response)
        console.log(response.data)
        console.log(response.headers)
        console.log(response.data.cookie)
        if (response.status === 200) {
          console.log("if works")
          
        }
      })
      .catch(function (error) {
        console.log(error);
      });

Request and Response image: Request and response image

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
  • 1
    Domain Cookies on IP addresses are a difficult thing as there is no consensus whether that is meaningful and how to handle them. Note that the port doesn't play a role in cookie identity and thus no CORS issues should happen here. Why are you trying to create a _domain_ cookie for the loopback address? This is pretty much nonsensical. – Volker Apr 08 '21 at 13:29
  • @Volker How should I create a cookie then? If I don't include those headers in the response I will get a CORS error on the browser's console. – noobProgrammer Apr 08 '21 at 13:46
  • 1
    I'm not talking about CORS, I'm talking about the cookie being a domain cookie. Don't get sidetracked by CORS. – Volker Apr 08 '21 at 14:21
  • @Volker Oh, I added the domain field after it wasn't working and I didn't know what else to try, but it didn't change anything, I can remove it right now and I will still get the same results. There was no reason in particular why I did it. Can you help me figure what is stopping the cookie from being set, please? – noobProgrammer Apr 08 '21 at 14:31
  • No, I cannot help you, but I know that making the cookie a domain cookie for an IP address is not going to help. – Volker Apr 08 '21 at 15:45

1 Answers1

2

You are marking the cookie as "secure" (HTTPS), however request to your API is being made via insecure (HTTP) connection.

The Secure attribute limits the scope of the cookie to "secure" channels (where "secure" is defined by the user agent). When a cookie has the Secure attribute, the user agent will include the cookie in an HTTP request only if the request is transmitted over a secure channel (typically HTTP over Transport Layer Security (TLS) Please see https://www.rfc-editor.org/rfc/rfc6265

You can try this below;

func Login(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
    // In case you don't have separate CORS middleware
    if r.Method == http.MethodOptions {
        header := w.Header()
        header.Set("Access-Control-Allow-Credentials", "true")
        header.Set("Access-Control-Allow-Headers", "Content-Type, withCredentials")
        header.Set("Access-Control-Allow-Origin", "http://localhost:3000")
        header.Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS")
        w.WriteHeader(http.StatusOK)
        return
    }
    
    http.SetCookie(w, &http.Cookie{Name: "sabor", Value: "merda", Path: "/", HttpOnly: false, SameSite: http.SameSiteNoneMode, Secure: false, Domain: "localhost"})
    
}

And from axios, just replace the endpoint to localhost; axios.post( "http://localhost:8080/login", ...

Community
  • 1
  • 1
sigkilled
  • 227
  • 1
  • 7
  • I thought Chrome treated localhost as secure starting from one of the recent versions, also after changing the secure bit to false the cookie is still not being set. Do you know if anything else could be causing it? – noobProgrammer Apr 09 '21 at 11:24
  • Actually it is not. You should use secure connection if you'd like to use secure cookies. Actually there is a tool written in go which can create and install locally trusted certificates. https://github.com/FiloSottile/mkcert. You can utilize it. Besides that, I would suggest you to set your CORS parameters to localhost. Then set your cookie's domain to localhost. – sigkilled Apr 09 '21 at 12:31