I have been having a difficult time implementing real time data streaming for our Next.JS app with authentication and am looking for advice. We are currently using the pages router and there are two additional apis behind Next.JS that handle most of the backend work. We are also using Auth0 (@auth0/nextjs-auth0) for user authentication to the app.
Currently our Kubernetes deployment is set up so that only the Next.JS standalone app is exposed to the internet. The two other apis we use (REST and GraphQL) reside in pods that are not exposed to the internet. We use Next.JS middleware to intercept all requests going to either of these apis and inject the necessary Auth0 authorization JWT as it travels to the backend APIs. This allows us to never expose the actual Auth0 JWT to the client which is desirable.
When trying to do data streaming with GraphQL we saw two options, either use web sockets or use server side events (SSE). we first opted for SSE (since these requests could go through our middleware on Next.JS to get the auth token) but then later found that there is limitation of only 6 open requests being allowed from a single web browser. Due to the nature of our data and the various subscriptions we hit all in parallel and then later stitch the data together, this was not a possible option.
We then turned to web sockets which we assumed would be a simple solution, however, we quickly learned that Next.JS has zero functionality available to support proxying web sockets out of the box. This meant that using middleware or api routes to proxy the web socket request would not work. This left us with two options:
-
Obtain the user’s Auth0 JWT on the client (through server side props or an API request) and make the request to a secondary server that only proxies the web socket.
-
Use a custom Next.JS server (likely with express) and add functionality to proxy the web socket through potentially obtaining the JWT in the custom server so it is never exposed to the client.
Currently we use option 1 but wonder if option 2 may be a better way to approach this (due to the JWT being leaked to the client). We are also open to any other ideas to achieve the same functionality. I did find this package that looks promising but we are not using the app router yet so its incompatible.
Thanks in advance for any help!