AWS Amplify Hosting で取れるリクエストヘッダー一覧 (Geo / ASN / デバイス情報)

2026-05-22 14:08 (23 days ago)
Header Buffet
この記事をテーマにした曲を再生

結論

AWS Amplify Hosting の SSR でリクエストハンドラに届くヘッダーには、CloudFront が付与する多くのユーザー情報が含まれている。

MaxMind や geoip-lite 等を導入しなくても、国名・都道府県・市区町村・郵便番号・緯度経度・ASN・デバイス種別 がそのまま取れる。

実際に届くヘッダー全部

本番デプロイで request.headers を全部ダンプしたところ、以下が確認できた:

Geo (位置情報) 系

ヘッダー名 値の例 意味
cloudfront-viewer-country JP ISO 3166-1 alpha-2 国コード
cloudfront-viewer-country-name Japan 国名 (英語)
cloudfront-viewer-country-region 13 ISO 3166-2 サブコード (東京都)
cloudfront-viewer-country-region-name Tokyo 都道府県/州名
cloudfront-viewer-city Matsubara 市区町村名
cloudfront-viewer-postal-code 156-0041 郵便番号
cloudfront-viewer-latitude 35.xxxxxx 緯度
cloudfront-viewer-longitude 139.xxxxxx 経度
cloudfront-viewer-time-zone Asia/Tokyo タイムゾーン

「郵便番号」「緯度経度」まで来る。プライバシー的に取り扱い注意。

市町村名は実際に私がアクセスしていた市町村名では無く、3Km程度離れていた。

ネットワーク系

ヘッダー名 値の例 意味
cloudfront-viewer-asn 25XX AS 番号
cloudfront-viewer-address 203.0.xxx.xxx:53xxx クライアント IP + ポート
cloudfront-viewer-tls TLSv1.3:TLS_AES_128_GCM_SHA256:connectionReused TLS バージョン + 暗号スイート
cloudfront-viewer-http-version 3.0 HTTP のバージョン
cloudfront-forwarded-proto https クライアント側のプロトコル
x-forwarded-for 203.0.xxx.xxx, 64.252.xxx.xxx プロキシ経路上の IP リスト
x-forwarded-host example.com クライアント側 Host
x-forwarded-port 443 クライアント側ポート
x-forwarded-proto https クライアント側プロトコル
via 3.0 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.cloudfront.net (CloudFront) CloudFront 経由情報

情報は一部匿名化しています。

ASN まで取れるのは美味しい。これがあれば「特定の ISP から来た」「AWS のデータセンターから来た」のような分類ができる。

デバイス種別

ヘッダー名 値の例
cloudfront-is-desktop-viewer true
cloudfront-is-mobile-viewer false
cloudfront-is-tablet-viewer false
cloudfront-is-smarttv-viewer false
cloudfront-is-ios-viewer false
cloudfront-is-android-viewer false

UA パースしなくてもデスクトップ/モバイル/タブレット/TV の判定ができる。CloudFront 側が UA を見て判定してくれる方式。

AWS 内部トレース系

ヘッダー名 用途
x-amzn-trace-id X-Ray 等のトレース ID
x-amz-cf-id CloudFront のリクエスト ID (サポート問い合わせ時に必要)

元のブラウザ由来 (上書きされていない!)

ヘッダー名 値の例
user-agent Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 ... Chrome/146.0.0.0 ...
accept-language ja,en-US;q=0.9,en;q=0.8
host example.com

過去 (2022 年頃) には「Amplify SSR は user-agentAmazon CloudFront に置換する」という GitHub issue (#2161) もあったが、現在は元のブラウザ UA が保持されているua-parser-js 等で詳細を抽出できる。

SvelteKit SSR での取得方法

load 関数や actions ハンドラの引数に渡ってくる request: Requestheaders から普通に取れる。

例: load 関数

// src/routes/+page.server.ts
import type { PageServerLoad } from './$types';

export const load: PageServerLoad = async ({ request }) => {
  const headers = request.headers;

  const country = headers.get('cloudfront-viewer-country-name'); // 'Japan'
  const region = headers.get('cloudfront-viewer-country-region-name'); // 'Tokyo'
  const asn = headers.get('cloudfront-viewer-asn'); // '25XX'

  return {
    location: { country, region, asn }
  };
};

例: action ハンドラ

// src/routes/+page.server.ts
import type { Actions } from './$types';

export const actions: Actions = {
  default: async ({ request }) => {
    const country = request.headers.get('cloudfront-viewer-country');
    // ...
  }
};

例: API endpoint (+server.ts)

// src/routes/api/some/+server.ts
import type { RequestHandler } from './$types';

export const GET: RequestHandler = async ({ request }) => {
  const country = request.headers.get('cloudfront-viewer-country');
  return new Response(JSON.stringify({ country }));
};

ユーティリティとしてまとめる

実プロジェクトでは、抽出ロジックをユーティリティ関数にまとめると扱いやすい。

// src/lib/server/geo.ts
export type DeviceType = 'desktop' | 'mobile' | 'tablet' | 'tv' | undefined;

export interface GeoInfo {
  country?: string;
  countryCode?: string;
  region?: string;
  asn?: number;
  deviceType?: DeviceType;
}

export function extractGeoInfo(headers: Headers): GeoInfo {
  const asnRaw = headers.get('cloudfront-viewer-asn');
  const asn = asnRaw ? parseInt(asnRaw, 10) : undefined;

  let deviceType: DeviceType;
  if (headers.get('cloudfront-is-tablet-viewer') === 'true') {
    deviceType = 'tablet';
  } else if (headers.get('cloudfront-is-mobile-viewer') === 'true') {
    deviceType = 'mobile';
  } else if (headers.get('cloudfront-is-smarttv-viewer') === 'true') {
    deviceType = 'tv';
  } else if (headers.get('cloudfront-is-desktop-viewer') === 'true') {
    deviceType = 'desktop';
  }

  return {
    country: headers.get('cloudfront-viewer-country-name') || undefined,
    countryCode: headers.get('cloudfront-viewer-country') || undefined,
    region: headers.get('cloudfront-viewer-country-region-name') || undefined,
    asn: asn !== undefined && Number.isFinite(asn) ? asn : undefined,
    deviceType
  };
}

呼び出し側:

import { extractGeoInfo } from '$lib/server/geo';

export const load: PageServerLoad = async ({ request }) => {
  const geo = extractGeoInfo(request.headers);
  console.log(geo);
  // { country: 'Japan', countryCode: 'JP', region: 'Tokyo', asn: 25XX, deviceType: 'desktop' }
};

参考

評価をお願いします (会員登録・ログイン不要)
現在の評価: 5.0 (1)
著者は、アプリケーション開発会社 Cyberneura を運営しています。
開発相談をお待ちしています。

アーカイブ