Subdomains and phoenix LiveView

I’m working on a white label to provide a free hosting alternative to meetup.com for elixir groups.

I got the domain elixir.group and I want to be able to sign up accounts as subdomains.

IE: pdx.elixir.group

This means that I must reconcile the subdomain dynamically and from an ecto repo.

Using a mesh up of custom plugs to route request to either a root router or a subdomain router
like seen in https://blog.gazler.com/blog/2015/07/18/subdomains-with-phoenix/ I later then in the mount of a LiveView look up the subdomain and render or return a 404 if the subdomain is not valid.

This is where things go south.

15:58:03.381 [error] Could not check origin for Phoenix.Socket transport.

Origin of the request: https://foo.elixir.group

This happens when you are attempting a socket connection to
a different host than the one configured in your config/
files. For example, in development the host is configured
to "localhost" but you may be trying to access it from
"127.0.0.1". To fix this issue, you may either:

  1. update [url: [host: ...]] to your actual host in the
     config file for your current environment (recommended)

  2. pass the :check_origin option when configuring your
     endpoint or when configuring the transport in your
     UserSocket module, explicitly outlining which origins
     are allowed:

        check_origin: ["https://example.com",
                       "//another.com:888", "//other.com"]

from the looks of this, there is only one way to dynamically set the check_origin though I’m not sure where that happens.

Also I thought I seen something about http2 requests over wss:// could be cross domain so long as its under the same wildcard SSL.

2 Likes

I think the correct place to check for the domain is in a custom plug at your router.ex or with a custom pipeline.

EDIT

See what I mean in this examples for creating Specific Plugs.

1 Like

config/config.exs:

config :app, App.Endpoint,
  check_origin: {App.Origin, :check_origin, []}

lib/app/origin.ex:

defmodule App.Origin do
  @spec check_origin(URI.t()) :: boolean
  def check_origin(%URI{} = origin) do
    # Check origin (query db etc), return true/ false
    origin.authority in ["a.app.com", "b.app.com"]
  end
end
7 Likes

Good to know your approach, but he needs to do it dynamically.

Yes, this is the way to go. App.Origin.check_origin/1 will be run for any new socket connection and can be used to compare the origin.authority against a db table or so.

1 Like

My bad, I just focus my attention in the hard-coded domains.

Thanks for the clarification.

1 Like

I don’t disagree that’s why I’m doing just that. The issue here is whether or not I can specify check_origin at run time or not.

1 Like

This is great thank you!

This might be interesting to you.

3 Likes