콘텐츠로 이동

방문자 식별자 Visitor ID

Visitor ID는 사용자가 로그인하지 않았거나 안정적으로 식별할 수 없는 상황에서 브라우저에 안정적인 익명 식별자를 생성하는 데 사용됩니다. Guance Browser RUM SDK는 이 값을 규칙에 매칭된 XHR 및 Fetch 요청 헤더에 주입하여 API 게이트웨이가 방문자별 속도 제한을 적용할 수 있게 하며, 동시에 현재 값을 RUM 이벤트의 context.visitor_id에 기록하여 연관 분석에 사용합니다.

Visitor ID는 속도 제한 버킷과 관측 가능성 연관 키로만 사용할 수 있으며, 인증, 테넌트 격리, 과금 또는 감사에는 사용할 수 없습니다.

버전 요구 사항: RUM SDK 3.3.15 이상 버전.

Visitor ID 활성화

datafluxRum.init()에서 visitorId를 구성합니다:

datafluxRum.init({
  applicationId: "<APPLICATION_ID>",
  site: "<PUBLIC_OPENWAY_URL>",
  clientToken: "<CLIENT_TOKEN>",
  visitorId: {
    enabled: true,
    header: "x-rum-visitor-id",
    match: [
      "https://api.example.com/",
      /^https:\/\/gateway\.example\.com\//,
      function (url) {
        return url.includes("/security/")
      }
    ],
    ttlHours: 24
  }
})
매개변수 유형 필수 여부 기본값 설명
enabled Boolean 아니요 false Visitor ID 활성화 여부. 명시적으로 true로 설정하지 않으면 식별자를 생성하거나 요청 헤더를 주입하지 않습니다.
header String 활성화 시 필수 없음 주입할 사용자 지정 요청 헤더 이름. 합법적인 소문자 쓰기 가능 요청 헤더여야 하며, 인증, CSRF, 서명, 분산 추적 요청 헤더 또는 SDK 리소스 연관 헤더 x-rum-resource-id는 사용할 수 없습니다.
match Array 활성화 시 필수 없음 비어 있지 않은 URL 매칭 목록으로, String, RegExp, Function을 지원합니다. 항목 중 하나라도 매칭되면 요청 헤더를 주입합니다.
ttlHours Number 아니요 24 Visitor ID 유효 시간(시간 단위)으로, 0보다 커야 합니다. 만료된 후 다음 사용 시 회전하며, 슬라이딩 갱신은 이루어지지 않습니다.

요청 매칭 규칙

match의 서로 다른 유형 규칙은 다음과 같은 방식으로 매칭됩니다:

  • String: 전체 URL의 접두사를 매칭하며, 반드시 동일한 Origin(프로토콜, 도메인, 포트)에 속해야 합니다. 예를 들어 https://api.example.comhttps://api.example.com.evil.test/를 매칭하지 않습니다.
  • RegExp: 전체 URL에 대해 정규식 매칭을 수행합니다.
  • Function: 전체 URL을 받아 Boolean을 반환합니다.

매칭 함수에서 발생한 예외는 SDK가 격리하며, 해당 규칙은 미매칭으로 처리되어 비즈니스 요청을 중단하지 않습니다. SDK 자체의 데이터 전송 요청에는 Visitor ID 헤더가 주입되지 않습니다.

브라우저 SDK는 초기화 이후에 시작된 XHR 및 Fetch만 처리합니다. 페이지 탐색, 이미지, 양식 제출, sendBeacon, WebSocket 및 Worker 내부 요청은 이 기능 범위에 포함되지 않습니다.

식별자 수명 주기

동일한 브라우저는 Visitor ID 유효 기간 동안 동일한 식별자를 재사용하며, 요청마다 새 값을 생성하지 않습니다. SDK는 식별자를 우선 localStorage에 저장합니다. 사용할 수 없는 경우 순서대로 sessionStorage와 현재 페이지 메모리로 폴백합니다:

저장 계층 재사용 범위
localStorage 동일한 오리진의 이후 페이지 방문 및 탭
sessionStorage 현재 탭 세션
페이지 메모리 현재 페이지 수명 주기

다음과 같은 경우 새 값이 생성됩니다:

  • 현재 Visitor ID가 ttlHours를 초과한 경우
  • 비즈니스에서 명시적으로 resetVisitorId()를 호출한 경우
  • 브라우저 저장소가 삭제되었거나 접근할 수 없고 기존 메모리 상태가 종료된 경우

여러 수준의 유효한 저장 기록이 존재하면 SDK는 가장 최신 기록을 선택합니다. 회전 후에는 새로고침해도 이전의 폴백 기록이 복원되지 않습니다.

로컬 저장에 성공하면 영구 식별자가 생성되고, 세션 저장소나 메모리로 폴백하면 세션 식별자가 생성됩니다. 비즈니스는 식별자 형식을 파싱하거나 의존해서는 안 됩니다.

요청 헤더 및 RUM 데이터

요청 헤더는 match에 매칭된 XHR 및 Fetch에만 주입됩니다. 기능을 활성화하면 현재 Visitor ID가 context.visitor_id로 RUM 이벤트에 기록됩니다. Visitor ID는 RUM Session, 사용자 식별자 및 Trace와 서로 독립적입니다:

  • sessionSampleRate 또는 tracingSampleRate는 Visitor ID 헤더 주입 여부를 결정하지 않습니다.
  • Visitor ID는 RUM Session을 생성하거나 강제 샘플링하지 않습니다.
  • 샘플링되지 않은 세션은 RUM 데이터를 전송하지 않지만, 매칭된 비즈니스 요청에는 Visitor ID 헤더가 계속 포함될 수 있습니다.
  • resetVisitorId()는 RUM Session, 사용자 식별자 또는 Trace를 변경하지 않습니다.

비즈니스에서 이미 visitorId.header와 동일한 이름의 요청 헤더를 설정한 경우, SDK는 현재 Visitor ID로 해당 값을 덮어쓰고 콘솔에 경고를 출력합니다. 이 요청 헤더는 SDK만 관리해야 합니다. match에 매칭되지 않은 요청은 injectTraceHeader가 반환한 동일한 이름의 헤더를 포함한 기존 요청 헤더를 유지합니다.

동일한 오리진 iframe에서 생성되어 현재 페이지의 fetch()로 전송되는 Request는 기존 요청 메서드, 요청 본문 및 비즈니스 요청 헤더를 유지합니다. 동일한 XHR의 send()가 매개변수 오류로 동기적으로 실패한 후 다시 전송되더라도 Visitor ID가 중복 추가되지 않습니다. 해당 요청에 이미 주입된 식별자는 재시도 중 회전이 발생해도 변경되지 않습니다.

글로벌, View 및 이벤트 사용자 정의 컨텍스트의 visitor_id는 SDK가 관리하는 값을 덮어쓰지 않습니다. 전송 전에 컨텍스트를 삭제하거나 조정해야 하는 경우에도 beforeSend를 사용할 수 있습니다.

초기화 전이나 원격 구성 대기 중에 버퍼링된 사용자 정의 이벤트는 SDK 시작 후 Visitor ID가 채워집니다. 이미 SDK 식별자 스냅샷이 있는 이벤트는 해당 스냅샷을 계속 사용하며, 이벤트 발생 시점의 다른 컨텍스트를 덮어쓰지 않습니다.

요청이 전송된 후, Resource가 완료되기 전에 Visitor ID가 회전하면 해당 Resource의 context.visitor_id는 요청 헤더에서 실제로 사용된 이전 값을 유지합니다. 회전 이후의 새 요청 및 기타 후속 RUM 이벤트는 새 값을 사용합니다.

명시적 회전

사용자가 로그아웃을 확인하거나 계정을 전환한 후 Visitor ID를 명시적으로 회전할 수 있습니다:

datafluxRum.resetVisitorId()

호출 후에는 이후 새로 시작되는 매칭 요청 및 후속 RUM 이벤트가 새 값을 사용합니다. 401, 인증되지 않은 요청 또는 반복적으로 트리거될 수 있는 다른 실패 분기에서 호출하지 마십시오. 그렇지 않으면 버킷을 계속 변경하게 되어 속도 제한 우회 통로가 됩니다.

CORS 및 보안 경계

사용자 지정 요청 헤더는 교차 출처 요청에서 CORS 사전 요청(preflight)을 트리거합니다. API 서비스는 Access-Control-Allow-HeadersvisitorId.header를 허용해야 하며, match는 신뢰할 수 있는 API만 포함해야 합니다.

Visitor ID는 클라이언트에서 생성되므로 사용자가 위조, 교체 또는 삭제할 수 있습니다. 게이트웨이는 이 값만으로 권한을 부여해서는 안 됩니다. 속도 제한 정책은 요청 헤더가 없는 요청을 위해 IP, 세션 또는 기타 비즈니스 차원의 폴백 규칙도 제공해야 하며, 차단 시간을 짧게 유지하여 공격자가 다른 방문자 ID를 도용해 오탐 차단을 유발하는 영향을 줄여야 합니다.

Cloudflare 속도 제한 예시

다음 Cloudflare Advanced Rate Limiting 템플릿에는 두 가지 규칙이 포함되어 있습니다. Visitor ID 헤더가 있으면 방문자 식별자 기준으로 집계하고, 요청 헤더가 없으면 원본 IP로 폴백합니다. 이는 선택적인 게이트웨이 배포 예시일 뿐, SDK 런타임 종속성이 아닙니다. Cloudflare를 사용하지 않는 비즈니스는 무시할 수 있습니다.

배포 전에 요청 경로, 요청 헤더 이름, 임계값 및 차단 시간을 수정해야 합니다. 규칙은 기본적으로 비활성화되어 있습니다. 먼저 생성하고 다시 읽어와 표현식, 집계 차원 및 임계값을 확인한 후에 활성화하십시오.

Cloudflare Advanced Rate Limiting 템플릿
{
  "name": "rum_visitor_id_rate_limit",
  "description": "Rate limit matched API requests by the RUM Visitor ID header, with an IP fallback when the header is missing.",
  "kind": "zone",
  "phase": "http_ratelimit",
  "rules": [
    {
      "description": "RUM Visitor ID API rate limit",
      "expression": "(starts_with(http.request.uri.path, \"/api/\") and len(http.request.headers[\"x-rum-visitor-id\"]) > 0)",
      "action": "block",
      "ratelimit": {
        "characteristics": [
          "cf.colo.id",
          "http.request.headers[\"x-rum-visitor-id\"]"
        ],
        "period": 60,
        "requests_per_period": 100,
        "mitigation_timeout": 600,
        "counting_expression": "(starts_with(http.request.uri.path, \"/api/\") and len(http.request.headers[\"x-rum-visitor-id\"]) > 0)",
        "requests_to_origin": true
      },
      "enabled": false
    },
    {
      "description": "Missing RUM Visitor ID IP fallback",
      "expression": "(starts_with(http.request.uri.path, \"/api/\") and len(http.request.headers[\"x-rum-visitor-id\"]) eq 0)",
      "action": "block",
      "ratelimit": {
        "characteristics": ["cf.colo.id", "ip.src"],
        "period": 60,
        "requests_per_period": 30,
        "mitigation_timeout": 600,
        "counting_expression": "(starts_with(http.request.uri.path, \"/api/\") and len(http.request.headers[\"x-rum-visitor-id\"]) eq 0)",
        "requests_to_origin": true
      },
      "enabled": false
    }
  ]
}

Cloudflare 규칙 형식은 API로 속도 제한 규칙 생성속도 제한 매개변수 설명을 참조하십시오.

문서 평가

이 페이지가 도움이 되었나요?