You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor Server应用中如何正确获取用户远程IP地址?

解决Blazor Server部署到IIS后无法获取远程IP的问题

问题原因

Blazor Server基于SignalR通信,初始页面加载时是HTTP请求,此时IHttpContextAccessor.HttpContext有效;但建立WebSocket连接后,后续组件交互不再依赖HTTP上下文,所以直接在组件中调用context.HttpContext会返回null。

有效解决方案

核心思路是在初始HTTP请求阶段捕获用户IP,将其保存到全局可访问的位置,供后续组件使用。

方法1:通过级联值(CascadingValue)传递IP

  1. 在根组件App.razor中捕获初始请求的IP:
@inject IHttpContextAccessor HttpContextAccessor

<CascadingValue Value="RemoteIpAddress">
    <Router AppAssembly="@typeof(App).Assembly">
        <Found Context="routeData">
            <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
            <FocusOnNavigate RouteData="@routeData" Selector="h1" />
        </Found>
        <NotFound>
            <PageTitle>Not found</PageTitle>
            <LayoutView Layout="@typeof(MainLayout)">
                <p role="alert">Sorry, there's nothing at this address.</p>
            </LayoutView>
        </NotFound>
    </Router>
</CascadingValue>

@code {
    private string? RemoteIpAddress { get; set; }

    protected override void OnInitialized()
    {
        // 获取直接连接的IP
        var ip = HttpContextAccessor.HttpContext?.Connection.RemoteIpAddress?.ToString();
        
        // 如果部署了反向代理(如IIS ARR),读取X-Forwarded-For头获取真实IP
        var forwardedFor = HttpContextAccessor.HttpContext?.Request.Headers["X-Forwarded-For"].FirstOrDefault();
        if (!string.IsNullOrEmpty(forwardedFor))
        {
            // X-Forwarded-For可能包含多个IP,取第一个(用户真实IP)
            ip = forwardedFor.Split(',').First().Trim();
        }

        RemoteIpAddress = ip;
    }
}
  1. 在需要的页面/组件中接收级联值:
@CascadingParameter string? RemoteIpAddress { get; set; }

<p>用户远程IP:@RemoteIpAddress</p>

方法2:使用全局状态容器存储IP

  1. 创建状态容器类:
public class AppState
{
    public string? RemoteIpAddress { get; set; }
}
  1. 在Program.cs中注册为单例:
builder.Services.AddSingleton<AppState>();
// 确保已注册IHttpContextAccessor
builder.Services.AddHttpContextAccessor();
  1. 在App.razor中初始化IP:
@inject IHttpContextAccessor HttpContextAccessor
@inject AppState AppState

<Router AppAssembly="@typeof(App).Assembly">
    <!-- 路由内容 -->
</Router>

@code {
    protected override void OnInitialized()
    {
        var ip = HttpContextAccessor.HttpContext?.Connection.RemoteIpAddress?.ToString();
        var forwardedFor = HttpContextAccessor.HttpContext?.Request.Headers["X-Forwarded-For"].FirstOrDefault();
        
        if (!string.IsNullOrEmpty(forwardedFor))
        {
            ip = forwardedFor.Split(',').First().Trim();
        }

        AppState.RemoteIpAddress = ip;
    }
}
  1. 在组件中注入状态容器获取IP:
@inject AppState AppState

<p>用户远程IP:@AppState.RemoteIpAddress</p>

注意事项

  • 如果你的IIS部署了反向代理或负载均衡,需要确保IIS已启用传递X-Forwarded-For请求头,否则获取到的会是代理服务器的IP而非用户真实IP。
  • 两种方法都仅能捕获初始请求的IP,如果用户在会话中切换网络,IP不会自动更新(Blazor Server无实时检测网络变化的机制)。

内容的提问来源于stack exchange,提问作者therehere3

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 19:39:51