Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

How do I get client information such as IP adress and browser name/version in Blazor server-side?

like image 793
jsmars Avatar asked Sep 17 '19 21:09

jsmars


People also ask

What is client side Blazor?

Client-side Blazor makes use of WebAssembly, which is used to run high-level languages on browsers. Necessary . NET WebAssembly-related code and its dependencies are downloaded to the browser, and the app is executed directly on the browser UI thread. All UI updates and event handling occur within the same process.

How do I run Blazor from command line?

Open a command prompt where you want your project to be located and run the following command. Run the cd BlazorServerApp command to navigate to the BlazorServerApp folder. Run the apllication. The dotnet run command runs the application.

How does server side Blazor work?

Server-side Blazor is executed on the server within an ASP.NET Core application. All UI updates, event handling, and JavaScript calls are handled from server by using a SignalR connection, even a button click will go to server.


1 Answers

Here's how to do it in server side Blazor for .NET 5 in 2021.

Please note that my solution will only provide you an IP address, but getting an user agent should be easy using my solution.

I will just copy the contents of my blog post available here: https://bartecki.me/blog/Blazor-serverside-get-remote-ip

TLDR:

You can use JavaScript to call your own exposed endpoint that will return remote connection IP using following code:

RemoteIpAddress = Request.HttpContext.Connection.RemoteIpAddress.ToString() 

... with the downside of having to handle your reverse proxy server if you have any, otherwise you will just get your reverse proxy's IP address.

or you can call an external endpoint using JavaScript that will return an IP address for you with the downside that you will have to configure CORS and even then it can be blocked by some adblocking extensions.

Details:

Two approaches

Approach 1: Call an external service using JavaScript

Pros:

  • Slightly more simpler if you are using reverse proxy like nginx, traefik

Cons:

  • May be blocked by external extensions/adblockers
  • You will have to configure CORS
_Host.cshtml
<script>
  window.getIpAddress = () => {
    return fetch('https://jsonip.com/')
      .then((response) => response.json())
      .then((data) => {
        return data.ip
      })
  }
</script>
RazorPage.razor.cs
    public partial class RazorPage : ComponentBase
    {
        [Inject] public IJSRuntime jsRuntime { get; set; }

        public async Task<string> GetIpAddress()
        {
            try
            {
                var ipAddress = await jsRuntime.InvokeAsync<string>("getIpAddress")
                    .ConfigureAwait(true);
                return ipAddress;
            }
            catch(Exception e)
            {
                //If your request was blocked by CORS or some extension like uBlock Origin then you will get an exception.
                return string.Empty;
            }
        }
    }
Startup.cs
        public void ConfigureServices(IServiceCollection services)
        {
            //code...
            services
                .AddCors(x => x.AddPolicy("externalRequests",
                    policy => policy
                .WithOrigins("https://jsonip.com")));
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            //code...
            app.UseCors("externalRequests");
        }

Approach 2: Expose an endpoint in our Blazor app and call it using JavaScript

Pros:

  • You won't have to configure CORS
  • Won't be blocked by extensions or adblockers

Cons:

  • May be slightly more complicated if you are using a reverse proxy like nginx, traefik, etc.

Now take care as you will use this approach, because if you are using a reverse proxy, then you will actually receive your reverse proxy IP address. It is very possible that your reverse proxy is already forwarding an IP address of the external client in some sort of header, but it is up to you to figure it out.

Example: https://www.nginx.com/resources/wiki/start/topics/examples/forwarded/

InfoController.cs
    [Route("api/[controller]")]
    [ApiController]
    public class InfoController : ControllerBase
    {
        [HttpGet]
        [Route("ipaddress")]
        public async Task<string> GetIpAddress()
        {
            var remoteIpAddress = this.HttpContext.Request.HttpContext.Connection.RemoteIpAddress;
            if (remoteIpAddress != null)
                return remoteIpAddress.ToString();
            return string.Empty;
        }
    }
Startup.cs
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers(); //remember to map controllers if you don't have this line
                endpoints.MapBlazorHub();
                endpoints.MapFallbackToPage("/_Host");
            });
_Host.cshtml
<script>
  window.getIpAddress = () => {
    return fetch('/api/info/ipaddress')
      .then((response) => response.text())
      .then((data) => {
        return data
      })
  }
</script>
RazorPage.razor.cs
    public partial class RazorPage : ComponentBase
    {
        [Inject] public IJSRuntime jsRuntime { get; set; }

        public async Task<string> GetIpAddress()
        {
            try
            {
                var ipAddress = await jsRuntime.InvokeAsync<string>("getIpAddress")
                    .ConfigureAwait(true);
                return ipAddress;
            }
            catch(Exception e)
            {
                //If your request was blocked by CORS or some extension like uBlock Origin then you will get an exception.
                return string.Empty;
            }
        }
    }
like image 156
Konrad Bartecki Avatar answered Oct 04 '22 06:10

Konrad Bartecki