Cross-Origin Access for LiveView

Background

I’m creating a Shopify app with Phoenix LiveView and I’m using their app proxy functionality. Using the app proxy functionality means the liveview live/websocket endpoint will be accessed from a different domain.

Current Behavior

I’ve tried specifying the hostname when initializing the LiveSocket, but it still fails to make the connection. I just receive the following message:

WebSocket connection to 'wss://trackboost.gigalixirapp.com/live/websocket?_csrf_token=YHUNJDkpaRkJNiEZQQoQOWwYPWQwDBoPTX4TkfQ-sfxtxIWp6uPItIvB&_mounts=0&vsn=2.0.0' failed:

Then it keeps trying, and failing, to make the connection. The main difference I notice between the requests my to the websocket in the normal app and the request through this proxy mechanism is the absence of a cookie when going through the proxy. I’m assuming that’s the root of the issue, but I’m not sure how to resolve it.

Current Code

app.js

const websocketHost = window.HOSTNAME.replace("http", "ws");
let csrfToken = document?.querySelector("meta[name='csrf-token']").getAttribute("content");
let liveSocket = new LiveSocket(
  `${websocketHost}/live`,
  Socket,
  {
    params: {_csrf_token: csrfToken},
    dom: {
      onBeforeElUpdated(from, to){
        if(from._x_dataStack){ window.Alpine.clone(from, to); }
      }
    },
    hooks
  }
);

// Connect if there are any LiveViews on the page
liveSocket.connect();

Did you add the host to your endpoint config check_origin list in your prod.exs?

4 Likes

That did the trick! Thanks!

2 Likes

That seems to have fixed the original problem I was having, but I’m seeing other issues now. It seems like there are errors from the websocket now. Again, these issues are only present when trying to access the page through the proxy. When accessing directly through the app everything works fine. Here is what I see from the logs.

receive error lv:phx-FqqOSMWOx9pMugJB phx_reply (4) {response: {…}, status: "error"}
app-27cbdd82331c70edda17bb59a648edaf.js?vsn=d:2 phx-FqqOSMWOx9pMugJB error: unable to join -  {reason: "stale"}
app-27cbdd82331c70edda17bb59a648edaf.js?vsn=d:2 phx-FqqOSMWOx9pMugJB destroyed: the child has been removed from the parent -  undefined
app-27cbdd82331c70edda17bb59a648edaf.js?vsn=d:2 push lv:phx-FqqOSMWOx9pMugJB phx_leave (4, 5) {}
app-27cbdd82331c70edda17bb59a648edaf.js?vsn=d:2 channel leave lv:phx-FqqOSMWOx9pMugJB undefined
app-27cbdd82331c70edda17bb59a648edaf.js?vsn=d:2 channel close lv:phx-FqqOSMWOx9pMugJB 4 undefined
app-27cbdd82331c70edda17bb59a648edaf.js?vsn=d:2 phx-FqqOSMWOx9pMugJB join: encountered 239 consecutive reloads -  undefined
app-27cbdd82331c70edda17bb59a648edaf.js?vsn=d:2 phx-FqqOSMWOx9pMugJB join: exceeded 10 consecutive reloads. Entering failsafe mode -  undefined
app-27cbdd82331c70edda17bb59a648edaf.js?vsn=d:2 receive ok lv:phx-FqqOSMWOx9pMugJB phx_reply (5) {response: {…}, status: "ok"}
app-27cbdd82331c70edda17bb59a648edaf.js?vsn=d:2 transport close CloseEvent {isTrusted: true, wasClean: true, code: 1005, reason: "", type: "close", …}
1 Like