czi*_*mba 5 sockets ip elixir phoenix-framework
如何从phoenixframework中的套接字获取remote_ip?我可以从View中的conn中获得它,但不能从Channel中获得它。
非常感谢您的帮助!
此处提供的答案副本: https: //elixirforum.com/t/phoenix-socket-channels-security-ip-identification/1463/3(所有功劳都归于https://elixirforum.com/u/arjan)
凤凰1.4更新:
从 Phoenix 1.4 开始,您可以从底层传输获取连接信息。您获得的信息类型取决于传输,但通过 WebSocket 传输,可以检索对等信息(IP 地址)和 x- 标头列表(用于 x-forwarded-for 解析)。
在你的endpoint.ex中像这样配置你的套接字:
socket("/socket", MyApp.Web.UserSocket,
websocket: [connect_info: [:peer_data, :x_headers]],
longpoll: [connect_info: [:peer_data, :x_headers]]
)
Run Code Online (Sandbox Code Playgroud)
然后你的 UserSocket 模块必须公开一个 connect/3 函数,如下所示:
def connect(_params, socket, connect_info) do
{:ok, socket}
end
Run Code Online (Sandbox Code Playgroud)
连接时,connect_info 参数现在包含来自传输的信息:
info: %{
peer_data: %{address: {127, 0, 0, 1}, port: 52372, ssl_cert: nil},
x_headers: []
}
Run Code Online (Sandbox Code Playgroud)
更新
如果您的 Phoenix 应用程序不直接处理流量,而是从反向代理(如 nginx)接收流量,那么peer_data将拥有 nginx IP 地址,而不是客户端的 IP 地址。要解决此问题,您可以告诉 nginx(或您使用的任何代理)在标头中传递原始 IP,然后稍后读取它。
所以你的凤凰城位置应该是这样的:
location /phoenix/ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://phoenix/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
Run Code Online (Sandbox Code Playgroud)
你的套接字代码应该有这样的:
defp get_ip_address(%{x_headers: headers_list}) do
header = Enum.find(headers_list, fn {key, _val} -> key == "x-real-ip" end)
case header do
nil ->
nil
{_key, value} ->
value
_ ->
nil
end
end
defp get_ip_address(_) do
nil
end
Run Code Online (Sandbox Code Playgroud)
并改变连接到这样的东西
def connect(params, socket, connect_info) do
socket = assign(socket, :ip_address, get_ip_address(connect_info))
{:ok, socket}
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
607 次 |
| 最近记录: |