How to authenticate with Node.js/Express + Passport + Websockets?

I am building an angular2-login-seed that uses Passport.js with OAuth strategies for authentication. Obviously the default method of authentication with these tools is use of an HTTP cookie signed by express. Passport, from what I can tell, manages the actual Set Cookie header so that express can authenticate each subsequent request via request.isAuthenticated() and access the data set by passport via req.session.passport.dataHere.

I want to incorporate realtime data in the application via websockets. This of course means a socket stream coming from the server to the client. This communication is entirely separate from a regular HTTP server request meaning:

  1. It does not contain the HTTP cookie that all HTTP requests contain

  2. Express does not broker the interaction with sockets, it is managed with whatever implementation is used in the backend (sock.js, socket.io)

This makes it difficult to streamline authentication between HTTP requests to express, and websocket data to the backend as they are separate methods of communication.

From my research, this leaves me with two options. One of which is to use a library to give my socket implementation (preferably sock.js over socket.io but I need to do more research) access to the express session. Then I could authenticate the socket connection however I want. Issue is I have no idea how I would get the express cookie into the stream from the front since javascript cannot access it (HTTP only cookie).

Another common solution I've seen people jump to is to use JWTs (JSON Web Tokens). Implementations revolving around this store the JWT in localstorage on the front end. This is so the SPA (in my case Angular2 services) could send it with every request for 'stateless' server authentication AND we could send it via a websocket to authenticate the websocket connection as well (the front end JS has access to localstorage obviously). A couple things that come to mind when thinking about this implementation:

  1. Is it even possible to have Passport OAuth strategies use JWT instead of the regular session information? What modification would this entail? From what I can tell the Passport strategies use some form of OAuth1 or OAuth2 parent strategies for authentication which defaults to using cookies.

  2. Would storing this vital information in localstorage open the application up to security breaches (XSS, CSRF, etc)

  3. If so, the most common workaround I've seen is to store the JWT in a cookie so it cannot be as easily accessed, spoofed, or forged. However this puts me back in the position I was in before using JWT, so might as well not bother.

  4. Does this mean I'd have to use some sort of state management store in the backend (Redis for example) to manage the authentication and decoding of the JWT body? (I know nothing about Redis, etc).

The idea of connecting authentication between server HTTP requests and socket data is odd but seemingly vital to properly authenticating a socket connection. I'm a little surprised an easier method does not exist. I've done some research and have seen things such as socketio-jwt, express-jwt, etc however I don't know if this would be a manageable transition with my Passport strategies, or if it would be easier opening up express session data to the socket implementation, or if I'm going about it all wrong!

Any help or guidance would be much appreciated thanks.

node.jssocketsexpresscookiespassport.js

Answers

answered 1 year ago Maarethyu #1

Then I could authenticate the socket connection however I want. Issue is I have no idea how I would get the express cookie into the stream from the front since javascript cannot access it (HTTP only cookie).

With express-socket.io-session the session auth is done on handshake, and the handshake is a http request, so even if your cookies are http-only it will work. (Tested by myself)

comments powered by Disqus