heroku 将Elixir Phoenix请求从根域重定向到www

xurqigkl  于 2023-10-19  发布在  Phoenix
关注(0)|答案(3)|浏览(178)

我们在Heroku上有一个Phoenix应用程序,在53号公路上有DNS。我们遵循这篇博客文章来设置正确的http到https重定向:
http://building.vts.com/blog/2015/11/02/route53-ssl-naked-domain-redirect/
一切工作和所有剩下的是重定向根到子域www。
有没有推荐的方法来设置这个在Phoenix城的方式?

ds97pgxw

ds97pgxw1#

只需在应用端点顶部的重定向中输入plug即可。
lib/app/endpoint.ex中:

defmodule App.Endpoint do
  use Phoenix.Endpoint, otp_app: :app

  socket "/socket", App.UserSocket

  plug App.Plugs.WWWRedirect
  # ...
end

lib/app/plugs/www_redirect.ex中:

defmodule App.Plugs.WWWRedirect do
  import Plug.Conn

  def init(options) do
    options
  end

  def call(conn, _options) do
    if bare_domain?(conn.host) do
      conn
        |> Phoenix.Controller.redirect(external: www_url(conn))
        |> halt
    else
      conn # Since all plugs need to return a connection
    end
  end

  # Returns URL with www prepended for the given connection. Note this also
  # applies to hosts that already contain "www"
  defp www_url(conn) do
    "#{conn.scheme}://www.#{conn.host}"
  end

  # Returns whether the domain is bare (no www)
  defp bare_domain?(host) do
    !Regex.match?(~r/\Awww\..*\z/i, host)
  end
end

请注意,由于lib中的任何内容都没有重新加载,因此需要重新启动服务器才能使其生效。

k5hmc34c

k5hmc34c2#

您还可以使用plug_canonical_host来处理它,并确保您的Elixir应用程序只能通过其规范URL访问。

f0brbegy

f0brbegy3#

为了完成fny的anser,我将添加完整的请求路径和查询字符串:

defmodule App.Plugs.WWWRedirect do
  import Plug.Conn

  def init(options) do
    options
  end

  def call(conn, _options) do
    if bare_domain?(conn.host) do
      conn
      |> Phoenix.Controller.redirect(external: www_url(conn))
      |> halt
    else
      # Since all plugs need to return a connection
      conn
    end
  end

  # Returns URL with www prepended for the given connection. Note this also
  # applies to hosts that already contain "www"
  defp www_url(%{query_string: ""} = conn) do
    "#{conn.scheme}://www.#{conn.host}#{conn.request_path}"
  end

  defp www_url(conn) do
    "#{conn.scheme}://www.#{conn.host}#{conn.request_path}?#{conn.query_string}"
  end

  # Returns whether the domain is bare (no www)
  defp bare_domain?(host) do
    !Regex.match?(~r/\Awww\..*\z/i, host)
  end
end

相关问题