6

I created a server-side app with Blazor and I want get the ip and user-agent with each page request, how can I achieve that? In a .NET Core app I just need to use this code in the controller:

var userAgent  = Request.Headers["User-Agent"].ToString()

But in Blazor I can't retrieve this data.

PeterJ
  • 3,705
  • 28
  • 51
  • 71
Soroush Asadi
  • 71
  • 1
  • 4

2 Answers2

17

User agent:

You can get it via JavaScript interop. Follow this easy steps:

On your _Host.cshtml file:

<script>
window.getUserAgent = () => {
    return navigator.userAgent;
};
</script>

To get user agent on any Blazor page:

var remoteUserAgent = await JSRuntime.InvokeAsync<string>("getUserAgent");

enter image description here

Notice you don't need to send user agent on each request, you can send it with your first request, all other client-side communication will be through the same socket.

Remote IP:

Bad news: "There is no a good way to do this at the moment. We will look into how we can provide make this information available to the client." more info at How do I get client IP and browser info in Blazor?

Edited Dec 31, 2019:

I guess I overthink about how to access to HttpContext. Reading some @enet comments and "How to use the HttpContext object in server-side Blazor to retrieve information about the user, user agent" post, I realize that you can access HttpContext via first request and not via SignalR requests. I mean, Blazor Server sends the App to client (browser) via Http Request, at this moment, when Blazor server app is served to client, you have access to HttpContext. I copy-paste Michael Washington's answer here (now is removed), this answer is very closed to Soroush Asadi's comment:

In your startup file add to ConfigureServices(IServiceCollection services):

services.AddHttpContextAccessor();

In a .razor page add:

@using Microsoft.AspNetCore.Http
@inject IHttpContextAccessor httpContextAccessor

//Then call:

httpContextAccessor.HttpContext.Connection?.RemoteIpAddress.ToString();
dani herrera
  • 48,760
  • 8
  • 117
  • 177
  • and for remote-ip address we can do these steps : 1- services.AddHttpContextAccessor(); 2- in @code {} var request = httpContextAccessor.HttpContext; 3- var remoteIp = request.Connection.RemoteIpAddress – Soroush Asadi Dec 28 '19 at 08:49
  • try services.AddControllers(); – Soroush Asadi Dec 31 '19 at 07:26
  • Since you can get the http context, you can always get the user agent from it too: `var userAgent = httpContextAccessor.HttpContext?.Request.Headers["User-Agent"];` – hillin Jul 07 '21 at 04:42
  • be careful doing the httpContextAccessor.HttpContext.Connection?.RemoteIpAddress.ToString(); trick. When i did this then published to Azure I would get "OAuth2 Authorization code was already redeemed, please retry with a new valid code or use an existing refresh token." error when I tried to authenticate using Azure AD. It worked fine when I tested locally, and this error only occurred when publishing to Azure. I spent 4 days diagnosing this to figure out this was the cause!! – Daniel Barnes Dec 08 '22 at 09:05
0

Also answered in: How do I get client IP and browser info in Blazor?

There's numerous examples of what to add to _Host.cshtml.cs to get an anti-forgery token. You can piggy-back that by adding to that code in _Host.cshtml as follows:

@{
    var initialTokenState = new InitialApplicationState
        {
            XsrfToken = Xsrf.GetAndStoreTokens(HttpContext).RequestToken,
            Cookie = HttpContext.Request.Cookies[".AspNetCore.Cookies"]
        };
    // try X-Forwarded-For first
    HttpContext.Request.Headers.TryGetValue("X-Forwarded-For", out var forwardedFor);
    if (forwardedFor.Count > 0)
        initialTokenState.RemoteIp = forwardedFor[0];
    else
        initialTokenState.RemoteIp = HttpContext.Connection.RemoteIpAddress?.ToString();
}

This exists for the life of the circuit and there's no way the remote IP changes while a circuit exists.

This answer only solves the client IP address half of the question.

David Thielen
  • 28,723
  • 34
  • 119
  • 193