8
votes

Here's my setup: I'm building a service (using Negroni and Gorilla) with user login, where upon login, the user gets a session cookie which the server uses to authorize protected endpoints. One of the protected endpoints allows the user/client to open a websocket with the server, like so:

app := negroni.New()

r := mux.NewRouter()

r.HandleFunc("/auth/connection", func(rw http.ResponseWriter, req *http.Request) {
    // authorize request using req.Cookie("session_id")

    // create websocket
    conn, err := upgrader.Upgrade(rw, req, nil)
    if err != nil {
        panic(err)
    }
    defer conn.Close()

    // do stuff...
})

app.UseHandler(r)

app.Run(":3000")

However, req.Cookies() is always empty, meaning I can't authorize any requests to "/auth/connection" -- and I'm almost positive it is not a problem with the websocket client (if you're curious, I'm testing it using this Python package: https://github.com/liris/websocket-client). Am I approaching authentication of a websocket correctly?

Any help/advice would be greatly appreciated!

1
Print req.Header to view the headers sent by the client. If the you don't see the cookie header or it's malformed in some way, then the problem is with the client library or application. - Cerise Limón
The server handles the WebSocket handshake as a normal HTTP request up to the point where upgrade is called. The Gorilla package is not in play at the line of code with the auth comment. - Cerise Limón
Yup, you were right -- the cookie was malformed and wasn't being parsed into req.Cookies correctly. Thanks fro the help! - Cody
Please mark this as answered so that it doesn't show up in the unanswered list. Or delete it entirely, since it is not a Go question in the end. - Jeff Allen

1 Answers

2
votes

The server handles the WebSocket handshake as a normal HTTP request up to the point where Upgrade is called. Use whatever authentication you would use for normal HTTP requests.

The Gorilla package is not in play at the line of code with the auth comment.