User-Agent Client Hints を取得する - ASP.NET Core

ASP.NET Coreアプリケーションで、User-Agent Client Hints を取得するコードを紹介します。

概要

新しいWebブラウザでは、ユーザーエージェントの情報を構造化された形式で取得できる User-Agent Client Hints が実装されています。 この記事では、ASP.NET Core アプリケーションで、User-Agent Client Hintsを取得するコードを紹介します。

実装方針

Webアプリケーションアクセス時のクライアントのリクエストヘッダの Sec-CH-UA の値を読み取ります。

実装例: ASP.NET Core アプリケーション

コード

ASP.NET Core アプリケーションのプロジェクトを作成し、以下のコードを記述します。
using Microsoft.AspNetCore.Http;

namespace UserAgentHint
{
  public class Program
  {
    public static void Main(string[] args)
    {
      var builder = WebApplication.CreateBuilder(args);
      var app = builder.Build();

      app.MapGet("/", async context =>
      {
        string UAHint = context.Request.Headers["Sec-CH-UA"];
        await context.Response.WriteAsync(UAHint);
      });

      app.Run();
    }
  }
}

解説

MapGetメソッドを呼び出し、"/"(アプリケーションルート)のGet時のマッピングを作成します。
  app.MapGet("/", async context =>
  {
  });

リクエストヘッダの Sec-CH-UA の値を UAHint変数に代入します。
  string UAHint = context.Request.Headers["Sec-CH-UA"];

UAHint変数の値をレスポンスとして返します。
  await context.Response.WriteAsync(UAHint);

実行結果

プロジェクトを実行し、アプリケーションルートのURLにアクセスします。下図の結果が表示されます。
"Microsoft Edge";v="125", "Chromium";v="125", "Not.A/Brand";v="24"


補足
httpのアクセス時にはUser-Agent Client Hintsの値はクライアントから送信されないため、空になります。

実装例: Razor Pages アプリケーション

Razor Pagesアプリケーションでの実装コードです。

コード

ASP.NET Coreアプリケーションを作成し、以下のコードを記述します。
Program.cs
namespace UserAgentHint
{
  public class Program
  {
    public static void Main(string[] args)
    {
      var builder = WebApplication.CreateBuilder(args);
      builder.Services.AddRazorPages();
      var app = builder.Build();

      app.UseRouting();
      app.MapRazorPages();
      app.Run();
    }
  }
}
Pages/Index.cshtml.cs
@page
@model UserAgentHint.Pages.IndexModel
@{
}
<html>
  <head>
    <title>User-Agent Client Hints Demo</title>
  </head>
  <body>
    <h1>User-Agent Client Hintsのデモ</h1>
    <p>User-Agent Client Hints : @Model.UAHint</p>
    <p>UACHints Mobile : @Model.UAHintMobile</p>
    <p>UACHints FullVersion : @Model.UAHintFullVersion</p>
    <p>UACHints Platform : @Model.UAHintPlatform</p>
    <p>UACHints PlatformVersion : @Model.UAHintPlatformVersion</p>
    <p>UACHints Arch : @Model.UAHintArch</p>
    <p>UACHints Bitness : @Model.UAHintBitness</p>
    <p>UACHints Model : @Model.UAHintModel</p>
  </body>
</html>
pages/Index.cshtml.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace UserAgentHint.Pages
{
  public class IndexModel : PageModel
  {
    public string UAHint { get; set; }
    public string UAHintMobile { get; set; }
    public string UAHintFullVersion { get; set; }
    public string UAHintPlatform { get; set; }
    public string UAHintPlatformVersion { get; set; }
    public string UAHintArch { get; set; }
    public string UAHintBitness { get; set; }
    public string UAHintModel { get; set; }

    public void OnGet()
    {
      UAHint = Request.Headers["Sec-CH-UA"];
      UAHintMobile = Request.Headers["Sec-CH-UA-Mobile"];
      UAHintFullVersion = Request.Headers["Sec-CH-UA-Full-Version"];
      UAHintPlatform = Request.Headers["Sec-CH-UA-Platform"];
      UAHintPlatformVersion = Request.Headers["Sec-CH-UA-Platform-Version"];
      UAHintArch = Request.Headers["Sec-CH-UA-Arch"];
      UAHintBitness = Request.Headers["Sec-CH-UA-Bitness"];
      UAHintModel = Request.Headers["Sec-CH-UA-Model"];
    }
  }
}

解説

Webアプリケーションのページにアクセスした際に、リクエストヘッダの値をページもデルのプロパティに代入しています。
以下のヘッダの値を読み出します。

ヘッダ名 意味
Sec-CH-UA User-Agent Client Hints の文字列
Sec-CH-UA-Mobile モバイルアクセスの情報
Sec-CH-UA-Full-Version ブラウザのフルバージョン
Sec-CH-UA-Platform プラットフォーム
Sec-CH-UA-Platform-Version プラットフォームのバージョン
Sec-CH-UA-Arch アクセス端末のアーキテクチャ
Sec-CH-UA-Bitness アクセス端末のCPUビット数
Sec-CH-UA-Model アクセス端末のモデル名

  UAHint = Request.Headers["Sec-CH-UA"];
  UAHintMobile = Request.Headers["Sec-CH-UA-Mobile"];
  UAHintFullVersion = Request.Headers["Sec-CH-UA-Full-Version"];
  UAHintPlatform = Request.Headers["Sec-CH-UA-Platform"];
  UAHintPlatformVersion = Request.Headers["Sec-CH-UA-Platform-Version"];
  UAHintArch = Request.Headers["Sec-CH-UA-Arch"];
  UAHintBitness = Request.Headers["Sec-CH-UA-Bitness"];
  UAHintModel = Request.Headers["Sec-CH-UA-Model"];

取得した値をRazorPage内に表示します。
  <p>User-Agent Client Hints : @Model.UAHint</p>
  <p>UACHints Mobile : @Model.UAHintMobile</p>
  <p>UACHints FullVersion : @Model.UAHintFullVersion</p>
  <p>UACHints Platform : @Model.UAHintPlatform</p>
  <p>UACHints PlatformVersion : @Model.UAHintPlatformVersion</p>
  <p>UACHints Arch : @Model.UAHintArch</p>
  <p>UACHints Bitness : @Model.UAHintBitness</p>
  <p>UACHints Model : @Model.UAHintModel</p>

実行結果

プロジェクトを実行し、アプリケーションルートのURLにアクセスすると下図のページが表示されます。
User-Agent Client Hintsの値やプラットフォームの値が表示されます。
ただし、すべての値は表示されず、低エントロピとして設定されている値のみが表示されます。

実装例: 高エントロピの値を取得する - Razor Pages アプリケーション

先の例では、User-Agent Client Hintsの値を取得できましたが、ほかの値は空欄の状態です。高エントロピとして定義されているほかの値を取得するコードを紹介します。
高エントロピのUser-Agent Client Hintsの値を取得する場合には、アクセス時のレスポンスヘッダに、Accept-CH を設定します。

先の実装コードから、RazorPagesのページモデルのコードを以下に変更します。
pages/Index.cshtml.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace UserAgentHint.Pages
{
  public class IndexModel : PageModel
  {
    public string UAHint { get; set; }
    public string UAHintMobile { get; set; }
    public string UAHintFullVersion { get; set; }
    public string UAHintPlatform { get; set; }
    public string UAHintPlatformVersion { get; set; }
    public string UAHintArch { get; set; }
    public string UAHintBitness { get; set; }
    public string UAHintModel { get; set; }

    public void OnGet()
    {
      UAHint = Request.Headers["Sec-CH-UA"];
      UAHintMobile = Request.Headers["Sec-CH-UA-Mobile"];
      UAHintFullVersion = Request.Headers["Sec-CH-UA-Full-Version"];
      UAHintPlatform = Request.Headers["Sec-CH-UA-Platform"];
      UAHintPlatformVersion = Request.Headers["Sec-CH-UA-Platform-Version"];
      UAHintArch = Request.Headers["Sec-CH-UA-Arch"];
      UAHintBitness = Request.Headers["Sec-CH-UA-Bitness"];
      UAHintModel = Request.Headers["Sec-CH-UA-Model"];

      Response.Headers.Add("Accept-CH", "Sec-CH-UA-Full-Version,Sec-CH-UA-Platform-Version,Sec-CH-UA-Arch,Sec-CH-UA-Bitness,Sec-CH-UA-Model");
    }
  }
}

解説

レスポンスヘッダに、Accept-CH ヘッダを設定し、取得したいUser-Agent Client Hintsの項目を値に設定します。複数の値を取得する場合は , で区切ります。
  Response.Headers.Add("Accept-CH", "Sec-CH-UA-Full-Version,Sec-CH-UA-Platform-Version,Sec-CH-UA-Arch,Sec-CH-UA-Bitness,Sec-CH-UA-Model");

実行結果

プロジェクトを実行し、アプリケーションルートのURLにアクセスします。 一度目のアクセスでは、レスポンスヘッダを返す前のため、先の例と同じ結果の表示になります。 ページをリロードすると、下図の表示となり、空欄であったUser-Agent Client Hintsの項目が取得できている状態になります。

Microsoft Edgeの場合の結果例

User-Agent Client Hints : "Microsoft Edge";v="125", "Chromium";v="125", "Not.A/Brand";v="24"
UACHints Mobile : ?0
UACHints FullVersion : "125.0.2535.51"
UACHints Platform : "Windows"
UACHints PlatformVersion : "15.0.0"
UACHints Arch : "x86"
UACHints Bitness : "64"
UACHints Model : ""

Google Chromeの場合の結果例

User-Agent Client Hints : "Google Chrome";v="125", "Chromium";v="125", "Not.A/Brand";v="24"
UACHints Mobile : ?0
UACHints FullVersion : "125.0.6422.60"
UACHints Platform : "Windows"
UACHints PlatformVersion : "15.0.0"
UACHints Arch : "x86"
UACHints Bitness : "64"
UACHints Model : ""
User-Agent Client Hints : "Chromium";v="124", "Google Chrome";v="124", "Not-A.Brand";v="99"
UACHints Mobile : ?0
UACHints FullVersion : "124.0.6367.209"
UACHints Platform : "macOS"
UACHints PlatformVersion : "14.2.1"
UACHints Arch : "x86"
UACHints Bitness : "64"
UACHints Model : ""

iPhoneの場合の結果例

iPhoneの場合は、SafariでもChromeでも空欄になります。

Androidの場合の結果例

Androidでは値が取得できます。
User-Agent Client Hints : "Google Chrome";v="125", "Chromium";v="125", "Not.A/Brand";v="24"
UACHints Mobile : ?1
UACHints FullVersion : "125.0.6422.60"
UACHints Platform : "Android"
UACHints PlatformVersion : "10.0.1"
UACHints Arch : ""
UACHints Bitness : ""
UACHints Model : "802SO"


著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
最終更新日: 2024-05-21
作成日: 2024-05-21
iPentec all rights reserverd.