programing

쿠키 또는 로컬 스토리지 없이 사용자 인식 가능

newsource 2022. 11. 7. 22:36

쿠키 또는 로컬 스토리지 없이 사용자 인식 가능

분석 툴을 구축하고 있으며 현재 사용자의 IP 주소, 브라우저 및 운영체제를 사용자 에이전트로부터 얻을 수 있습니다.

쿠키나 로컬 스토리지를 사용하지 않고 동일한 사용자를 탐지할 수 있는지 궁금합니다.여기서 코드 예는 기대하지 않습니다.어디서 더 자세히 봐야 하는지 간단히 힌트만 주세요.

같은 컴퓨터/디바이스의 경우 크로스 브라우저 호환성이 필요하다는 것을 잊지 않았습니다.기본적으로는 사용자가 아니라 디바이스 인식을 원합니다.

서론

제가 제대로 이해한 경우 고유 식별자가 없는 사용자를 식별해야 하므로 랜덤 데이터를 대조하여 해당 사용자가 누구인지 파악해야 합니다.다음과 같은 이유로 사용자의 ID를 안정적으로 저장할 수 없습니다.

  • 쿠키 삭제 가능
  • IP 주소 변경 가능
  • 브라우저 변경 가능
  • 브라우저 캐시가 삭제될 수 있습니다.

Java 애플릿 또는 Com Object는 하드웨어 정보의 해시를 사용하는 쉬운 솔루션이었지만, 오늘날 사람들은 보안을 너무 의식하고 있기 때문에 사람들이 이러한 종류의 프로그램을 시스템에 설치하도록 하는 것은 어려울 것입니다.따라서 쿠키 및 기타 유사한 도구를 사용해야 합니다.

쿠키 및 기타 유사한 도구

데이터 프로파일을 작성한 후 확률 테스트를 사용하여 가능성 있는 사용자를 식별할 수 있습니다.이것에 도움이 되는 프로파일은, 다음의 몇개의 편성으로 생성할 수 있습니다.

  1. IP 소
    • 실제 IP 주소
    • 프록시 IP 주소(사용자는 같은 프록시를 반복적으로 사용하는 경우가 많다)
  2. 쿠키
  3. 웹 버그(버그는 수정되지만 여전히 유용하기 때문에 신뢰성이 낮음)
    • PDF 버그
    • 플래시 버그
    • 자바 버그
  4. 브라우저
    • [추적(Tracking)]을 클릭합니다(많은 사용자가 방문 때마다 동일한 일련의 페이지를 방문합니다).
    • 브라우저 핑거프린트 - 설치된 플러그인(대부분의 경우 사람들은 다양하고 다소 고유한 플러그인 세트를 가지고 있습니다)
    • 캐시된 이미지(Cacheed Images) (Cookie는 삭제해도 캐시된 이미지는 남길 수 있음)
    • Blobs 사용
    • URL(예: https://stackoverflow.com/users/1226894 또는 http://www.facebook.com/barackobama?fref=ts) 등 URL에 고유한 사용자 ID가 포함되어 있을 수 있음)
    • 시스템 폰트 검출(이는 거의 알려지지 않았지만 종종 고유한 키 시그니처)
  5. HTML5 © Javascript
    • HTML5 로컬 스토리지
    • HTML5 지오로케이션 API 및 역 지오코딩
    • 아키텍처, OS 언어, 시스템 시간, 화면 해상도 등
    • 네트워크 정보 API
    • 배터리 상태 API

여기에 기재된 항목은 사용자를 고유하게 식별할 수 있는 몇 가지 방법뿐입니다.더 많이 있어요.

이 랜덤 데이터 요소 세트를 사용하여 데이터 프로파일을 구축하면 다음 단계는 무엇일까요?

다음 단계는 퍼지 논리, 더 나은 것은 인공 신경망을 개발하는 것입니다(퍼지 논리를 사용합니다).어느 경우든 시스템을 트레이닝하고 그 트레이닝을 베이지안 추론과 결합하여 결과의 정확도를 높이는 것이 목적입니다.

인공 뉴럴 네트워크

PHP용 NeuralMesh 라이브러리를 사용하면 인공 신경망을 생성할 수 있습니다.베이지안 추론을 구현하려면 다음 링크를 확인하십시오.

이 시점에서, 다음과 같이 생각할 수 있습니다.

단순해 보이는 작업에 수학과 논리가 많은 이유는 무엇입니까?

기본적으로 간단한 작업이 아니기 때문입니다.당신이 달성하려고 하는 것은 사실 순수한 확률입니다.예를 들어 다음과 같은 기존 사용자가 있습니다.

User1 = A + B + C + D + G + K
User2 = C + D + I + J + K + F

다음 데이터를 수신할 때:

B + C + E + G + F + K

당신이 기본적으로 묻고 있는 질문은 다음과 같습니다.

수신한 데이터(B + C + E + G + F + K)가 실제로 User1 또는 User2일 확률은 얼마입니까?그리고 그 두 가지 중 어떤 것이 가장 가능성이 높은가?

이 질문에 효과적으로 답하려면 빈도확률 형식과 결합 확률이 더 나은 접근 방식을 이해해야 합니다.자세한 내용은 여기에서는 설명하기가 어렵지만(그래서 링크를 제공하고 있습니다), 여러 증상을 조합하여 가능한 질병을 식별하는 의료 진단 마법사 응용 프로그램이 좋은 예입니다.

데이터 프로파일(위의 예에서는 B + C + E + G + F + K)을 증상으로 구성하고 알 수 없는 사용자를 질병으로 구성하는 일련의 데이터 포인트를 잠시 생각해 보십시오.질병을 식별함으로써 적절한 치료법을 추가로 식별할 수 있습니다(이 사용자를 User1로 취급).

두 가지 이상의 증상을 식별한 질병이 더 쉽게 식별할 수 있습니다.실제로 증상을 더 많이 식별할수록 진단이 더 쉽고 정확해질 것이 거의 확실합니다.

다른 대안이 있나요?

물론이야.다른 방법으로 간단한 스코어링 알고리즘을 작성하여 정확한 일치를 기반으로 할 수도 있습니다.이는 확률만큼 효율적이지는 않지만 구현이 더 간단할 수 있습니다.

예를 들어 다음과 같은 간단한 점수 차트를 생각해 보십시오.

+-------------------------+--------+------------+| 속성 | 중량 | 중요도 |+-------------------------+--------+------------+| 실제 IP 주소 | 60 | 5 || 사용된 프록시 IP 주소 | 40 | 4 || HTTP 쿠키 | 80 | 8 || 세션 쿠키 | 80 | 6 || 서드파티 쿠키 | 60 | 4 || Flash Cookie | 90 |7 || PDF 버그 | 20 | 1 || Flash Bug | 20 |1 || Java Bug | 20 | 1 || 자주 보는 페이지 | 40 | 1 || 브라우저 지문 | 35 | 2 || 설치된 플러그인 | 25 | 1 || 캐시된 이미지 | 40 | 3 || URL | 60 | 4 || 시스템 폰트 검출 | 70 |4 || 로컬 스토리지 | 90 |8 || 지리 위치 | 70 | 6 || AOLTR | 70 | 4 || 네트워크 정보 API | 40 | 3 || 배터리 상태 API | 20 | 1 |+-------------------------+--------+------------+

특정 요청에 따라 수집할 수 있는 각 정보에 대해 관련 점수를 부여한 다음 중요도를 사용하여 점수가 동일한 경우 충돌을 해결합니다.

개념 실증

간단한 개념 증명은 Perceptron을 참조하십시오.퍼셉트론은 패턴 인식 애플리케이션에 일반적으로 사용되는 RNA 모델입니다.완벽하게 구현된 오래된 PHP 클래스도 있지만 목적에 맞게 수정해야 할 수 있습니다.

훌륭한 도구이지만 Perceptron은 여전히 여러 결과(가능한 일치)를 반환할 수 있기 때문에 점수와 차이 비교를 사용하여 이러한 일치의 가장 좋은 점을 식별할 수 있습니다.

전제 조건

  • 각 사용자에 대해 가능한 모든 정보(IP, 쿠키 등)를 저장합니다.
  • 결과가 정확히 일치하는 경우 점수를 1씩 올립니다.
  • 결과가 정확하게 일치하지 않을 경우 점수를 1감소합니다.

기대.

  1. RNA 라벨 생성
  2. 데이터베이스를 에뮬레이트하는 랜덤 사용자 생성
  3. 알 수 없는 단일 사용자 생성
  4. 알 수 없는 사용자 RNA 및 값 생성
  5. 시스템은 RNA 정보를 병합하고 퍼셉트론을 학습할 것입니다.
  6. Perceptron을 교육한 후 시스템에 일련의 무게가 부여됩니다.
  7. 이제 알 수 없는 사용자의 패턴을 테스트할 수 있으며 Perceptron이 결과 세트를 생성합니다.
  8. 모든 양의 일치 항목 저장
  9. 먼저 점수를 기준으로 일치 항목을 정렬한 다음 차이(위 설명)를 기준으로 정렬합니다.
  10. 가장 가까운 두 개의 일치 항목을 출력하거나, 일치하는 항목이 없는 경우 빈 결과를 출력합니다.

개념 실증 코드

$features = array(
    'Real IP address' => .5,
    'Used proxy IP address' => .4,
    'HTTP Cookies' => .9,
    'Session Cookies' => .6,
    '3rd Party Cookies' => .6,
    'Flash Cookies' => .7,
    'PDF Bug' => .2,
    'Flash Bug' => .2,
    'Java Bug' => .2,
    'Frequent Pages' => .3,
    'Browsers Finger Print' => .3,
    'Installed Plugins' => .2,
    'URL' => .5,
    'Cached PNG' => .4,
    'System Fonts Detection' => .6,
    'Localstorage' => .8,
    'Geolocation' => .6,
    'AOLTR' => .4,
    'Network Information API' => .3,
    'Battery Status API' => .2
);

// Get RNA Lables
$labels = array();
$n = 1;
foreach ($features as $k => $v) {
    $labels[$k] = "x" . $n;
    $n ++;
}

// Create Users
$users = array();
for($i = 0, $name = "A"; $i < 5; $i ++, $name ++) {
    $users[] = new Profile($name, $features);
}

// Generate Unknown User
$unknown = new Profile("Unknown", $features);

// Generate Unknown RNA
$unknownRNA = array(
    0 => array("o" => 1),
    1 => array("o" => - 1)
);

// Create RNA Values
foreach ($unknown->data as $item => $point) {
    $unknownRNA[0][$labels[$item]] = $point;
    $unknownRNA[1][$labels[$item]] = (- 1 * $point);
}

// Start Perception Class
$perceptron = new Perceptron();

// Train Results
$trainResult = $perceptron->train($unknownRNA, 1, 1);

// Find matches
foreach ($users as $name => &$profile) {
    // Use shorter labels
    $data = array_combine($labels, $profile->data);
    if ($perceptron->testCase($data, $trainResult) == true) {
        $score = $diff = 0;

        // Determing the score and diffrennce
        foreach ($unknown->data as $item => $found) {
            if ($unknown->data[$item] === $profile->data[$item]) {
                if ($profile->data[$item] > 0) {
                    $score += $features[$item];
                } else {
                    $diff += $features[$item];
                }
            }
        }
        // Ser score and diff
        $profile->setScore($score, $diff);
        $matchs[] = $profile;
    }
}

// Sort bases on score and Output
if (count($matchs) > 1) {
    usort($matchs, function ($a, $b) {
        // If score is the same use diffrence
        if ($a->score == $b->score) {
            // Lower the diffrence the better
            return $a->diff == $b->diff ? 0 : ($a->diff > $b->diff ? 1 : - 1);
        }
        // The higher the score the better
        return $a->score > $b->score ? - 1 : 1;
    });

    echo "<br />Possible Match ", implode(",", array_slice(array_map(function ($v) {
        return sprintf(" %s (%0.4f|%0.4f) ", $v->name, $v->score,$v->diff);
    }, $matchs), 0, 2));
} else {
    echo "<br />No match Found ";
}

출력:

Possible Match D (0.7416|0.16853),C (0.5393|0.2809)

"D"의 Print_r:

echo "<pre>";
print_r($matchs[0]);


Profile Object(
    [name] => D
    [data] => Array (
        [Real IP address] => -1
        [Used proxy IP address] => -1
        [HTTP Cookies] => 1
        [Session Cookies] => 1
        [3rd Party Cookies] => 1
        [Flash Cookies] => 1
        [PDF Bug] => 1
        [Flash Bug] => 1
        [Java Bug] => -1
        [Frequent Pages] => 1
        [Browsers Finger Print] => -1
        [Installed Plugins] => 1
        [URL] => -1
        [Cached PNG] => 1
        [System Fonts Detection] => 1
        [Localstorage] => -1
        [Geolocation] => -1
        [AOLTR] => 1
        [Network Information API] => -1
        [Battery Status API] => -1
    )
    [score] => 0.74157303370787
    [diff] => 0.1685393258427
    [base] => 8.9
)

Debug = true이면 입력(센서 & 원하는 경우), 초기 가중치, 출력(센서, 합계, 네트워크), 오류, 수정최종 가중치를 볼 수 있습니다.

+----+----+----+----+----+----+----+----+----+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+------+-----+----+---------+---------+---------+---------+---------+---------+---------+---------+---------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----+----+----+----+----+----+----+----+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----------+
| o  | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | x10 | x11 | x12 | x13 | x14 | x15 | x16 | x17 | x18 | x19 | x20 | Bias | Yin | Y  | deltaW1 | deltaW2 | deltaW3 | deltaW4 | deltaW5 | deltaW6 | deltaW7 | deltaW8 | deltaW9 | deltaW10 | deltaW11 | deltaW12 | deltaW13 | deltaW14 | deltaW15 | deltaW16 | deltaW17 | deltaW18 | deltaW19 | deltaW20 | W1 | W2 | W3 | W4 | W5 | W6 | W7 | W8 | W9 | W10 | W11 | W12 | W13 | W14 | W15 | W16 | W17 | W18 | W19 | W20 | deltaBias |
+----+----+----+----+----+----+----+----+----+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+------+-----+----+---------+---------+---------+---------+---------+---------+---------+---------+---------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----+----+----+----+----+----+----+----+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----------+
| 1  | 1  | -1 | -1 | -1 | -1 | -1 | -1 | 1  | 1  | 1   | 1   | 1   | 1   | 1   | -1  | -1  | -1  | -1  | 1   | 1   | 1    | 0   | -1 | 0       | -1      | -1      | -1      | -1      | -1      | -1      | 1       | 1       | 1        | 1        | 1        | 1        | 1        | -1       | -1       | -1       | -1       | 1        | 1        | 0  | -1 | -1 | -1 | -1 | -1 | -1 | 1  | 1  | 1   | 1   | 1   | 1   | 1   | -1  | -1  | -1  | -1  | 1   | 1   | 1         |
| -1 | -1 | 1  | 1  | 1  | 1  | 1  | 1  | -1 | -1 | -1  | -1  | -1  | -1  | -1  | 1   | 1   | 1   | 1   | -1  | -1  | 1    | -19 | -1 | 0       | 0       | 0       | 0       | 0       | 0       | 0       | 0       | 0       | 0        | 0        | 0        | 0        | 0        | 0        | 0        | 0        | 0        | 0        | 0        | 0  | -1 | -1 | -1 | -1 | -1 | -1 | 1  | 1  | 1   | 1   | 1   | 1   | 1   | -1  | -1  | -1  | -1  | 1   | 1   | 1         |
| -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | --  | --  | --  | --  | --  | --  | --  | --  | --  | --  | --  | --   | --  | -- | --      | --      | --      | --      | --      | --      | --      | --      | --      | --       | --       | --       | --       | --       | --       | --       | --       | --       | --       | --       | -- | -- | -- | -- | -- | -- | -- | -- | -- | --  | --  | --  | --  | --  | --  | --  | --  | --  | --  | --  | --        |
| 1  | 1  | -1 | -1 | -1 | -1 | -1 | -1 | 1  | 1  | 1   | 1   | 1   | 1   | 1   | -1  | -1  | -1  | -1  | 1   | 1   | 1    | 19  | 1  | 0       | 0       | 0       | 0       | 0       | 0       | 0       | 0       | 0       | 0        | 0        | 0        | 0        | 0        | 0        | 0        | 0        | 0        | 0        | 0        | 0  | -1 | -1 | -1 | -1 | -1 | -1 | 1  | 1  | 1   | 1   | 1   | 1   | 1   | -1  | -1  | -1  | -1  | 1   | 1   | 1         |
| -1 | -1 | 1  | 1  | 1  | 1  | 1  | 1  | -1 | -1 | -1  | -1  | -1  | -1  | -1  | 1   | 1   | 1   | 1   | -1  | -1  | 1    | -19 | -1 | 0       | 0       | 0       | 0       | 0       | 0       | 0       | 0       | 0       | 0        | 0        | 0        | 0        | 0        | 0        | 0        | 0        | 0        | 0        | 0        | 0  | -1 | -1 | -1 | -1 | -1 | -1 | 1  | 1  | 1   | 1   | 1   | 1   | 1   | -1  | -1  | -1  | -1  | 1   | 1   | 1         |
| -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | --  | --  | --  | --  | --  | --  | --  | --  | --  | --  | --  | --   | --  | -- | --      | --      | --      | --      | --      | --      | --      | --      | --      | --       | --       | --       | --       | --       | --       | --       | --       | --       | --       | --       | -- | -- | -- | -- | -- | -- | -- | -- | -- | --  | --  | --  | --  | --  | --  | --  | --  | --  | --  | --  | --        |
+----+----+----+----+----+----+----+----+----+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+------+-----+----+---------+---------+---------+---------+---------+---------+---------+---------+---------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----+----+----+----+----+----+----+----+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----------+

x1 ~ x20은 코드에 의해 변환된 기능을 나타냅니다.

// Get RNA Labels
$labels = array();
$n = 1;
foreach ( $features as $k => $v ) {
    $labels[$k] = "x" . $n;
    $n ++;
}

여기 온라인 데모가 있습니다.

사용되는 클래스:

class Profile {
    public $name, $data = array(), $score, $diff, $base;

    function __construct($name, array $importance) {
        $values = array(-1, 1); // Perception values
        $this->name = $name;
        foreach ($importance as $item => $point) {
            // Generate Random true/false for real Items
            $this->data[$item] = $values[mt_rand(0, 1)];
        }
        $this->base = array_sum($importance);
    }

    public function setScore($score, $diff) {
        $this->score = $score / $this->base;
        $this->diff = $diff / $this->base;
    }
}

수정된 퍼셉트론 클래스

class Perceptron {
    private $w = array();
    private $dw = array();
    public $debug = false;

    private function initialize($colums) {
        // Initialize perceptron vars
        for($i = 1; $i <= $colums; $i ++) {
            // weighting vars
            $this->w[$i] = 0;
            $this->dw[$i] = 0;
        }
    }

    function train($input, $alpha, $teta) {
        $colums = count($input[0]) - 1;
        $weightCache = array_fill(1, $colums, 0);
        $checkpoints = array();
        $keepTrainning = true;

        // Initialize RNA vars
        $this->initialize(count($input[0]) - 1);
        $just_started = true;
        $totalRun = 0;
        $yin = 0;

        // Trains RNA until it gets stable
        while ($keepTrainning == true) {
            // Sweeps each row of the input subject
            foreach ($input as $row_counter => $row_data) {
                // Finds out the number of columns the input has
                $n_columns = count($row_data) - 1;

                // Calculates Yin
                $yin = 0;
                for($i = 1; $i <= $n_columns; $i ++) {
                    $yin += $row_data["x" . $i] * $weightCache[$i];
                }

                // Calculates Real Output
                $Y = ($yin <= 1) ? - 1 : 1;

                // Sweeps columns ...
                $checkpoints[$row_counter] = 0;
                for($i = 1; $i <= $n_columns; $i ++) {
                    /** DELTAS **/
                    // Is it the first row?
                    if ($just_started == true) {
                        $this->dw[$i] = $weightCache[$i];
                        $just_started = false;
                        // Found desired output?
                    } elseif ($Y == $row_data["o"]) {
                        $this->dw[$i] = 0;
                        // Calculates Delta Ws
                    } else {
                        $this->dw[$i] = $row_data["x" . $i] * $row_data["o"];
                    }

                    /** WEIGHTS **/
                    // Calculate Weights
                    $this->w[$i] = $this->dw[$i] + $weightCache[$i];
                    $weightCache[$i] = $this->w[$i];

                    /** CHECK-POINT **/
                    $checkpoints[$row_counter] += $this->w[$i];
                } // END - for

                foreach ($this->w as $index => $w_item) {
                    $debug_w["W" . $index] = $w_item;
                    $debug_dw["deltaW" . $index] = $this->dw[$index];
                }

                // Special for script debugging
                $debug_vars[] = array_merge($row_data, array(
                    "Bias" => 1,
                    "Yin" => $yin,
                    "Y" => $Y
                ), $debug_dw, $debug_w, array(
                    "deltaBias" => 1
                ));
            } // END - foreach

            // Special for script debugging
             $empty_data_row = array();
            for($i = 1; $i <= $n_columns; $i ++) {
                $empty_data_row["x" . $i] = "--";
                $empty_data_row["W" . $i] = "--";
                $empty_data_row["deltaW" . $i] = "--";
            }
            $debug_vars[] = array_merge($empty_data_row, array(
                "o" => "--",
                "Bias" => "--",
                "Yin" => "--",
                "Y" => "--",
                "deltaBias" => "--"
            ));

            // Counts training times
            $totalRun ++;

            // Now checks if the RNA is stable already
            $referer_value = end($checkpoints);
            // if all rows match the desired output ...
            $sum = array_sum($checkpoints);
            $n_rows = count($checkpoints);
            if ($totalRun > 1 && ($sum / $n_rows) == $referer_value) {
                $keepTrainning = false;
            }
        } // END - while

        // Prepares the final result
        $result = array();
        for($i = 1; $i <= $n_columns; $i ++) {
            $result["w" . $i] = $this->w[$i];
        }

        $this->debug($this->print_html_table($debug_vars));

        return $result;
    } // END - train
    function testCase($input, $results) {
        // Sweeps input columns
        $result = 0;
        $i = 1;
        foreach ($input as $column_value) {
            // Calculates teste Y
            $result += $results["w" . $i] * $column_value;
            $i ++;
        }
        // Checks in each class the test fits
        return ($result > 0) ? true : false;
    } // END - test_class

    // Returns the html code of a html table base on a hash array
    function print_html_table($array) {
        $html = "";
        $inner_html = "";
        $table_header_composed = false;
        $table_header = array();

        // Builds table contents
        foreach ($array as $array_item) {
            $inner_html .= "<tr>\n";
            foreach ( $array_item as $array_col_label => $array_col ) {
                $inner_html .= "<td>\n";
                $inner_html .= $array_col;
                $inner_html .= "</td>\n";

                if ($table_header_composed == false) {
                    $table_header[] = $array_col_label;
                }
            }
            $table_header_composed = true;
            $inner_html .= "</tr>\n";
        }

        // Builds full table
        $html = "<table border=1>\n";
        $html .= "<tr>\n";
        foreach ($table_header as $table_header_item) {
            $html .= "<td>\n";
            $html .= "<b>" . $table_header_item . "</b>";
            $html .= "</td>\n";
        }
        $html .= "</tr>\n";

        $html .= $inner_html . "</table>";

        return $html;
    } // END - print_html_table

    // Debug function
    function debug($message) {
        if ($this->debug == true) {
            echo "<b>DEBUG:</b> $message";
        }
    } // END - debug
} // END - class

결론

Unique Identifier 없이 사용자를 식별하는 것은 간단하거나 간단한 작업이 아닙니다.다양한 방법으로 사용자로부터 수집할 수 있는 충분한 양의 랜덤 데이터를 수집해야 합니다.

인공신경망을 사용하지 않기로 선택하더라도 우선 순위와 가능성이 있는 단순 확률 매트릭스를 사용하는 것이 좋습니다.그리고 위에 제시된 코드와 예가 당신에게 계속 진행하기에 충분하기를 바랍니다.

이 기법(쿠키 없이 또는 IP 주소 없이 동일한 사용자를 감지하는 것)을 브라우저 핑거프린트라고 합니다.기본적으로 브라우저에 대한 정보를 최대한 탐색할 수 있습니다. Javascript, Flash 또는 Java(설치된 확장자, 글꼴 등)를 사용하면 더 나은 결과를 얻을 수 있습니다.그런 다음 원하는 경우 결과를 해시할 수 있습니다.

틀림없는 건 아니지만

표시되는 브라우저의 83.6%가 고유 지문을 가지고 있으며, Flash 또는 Java를 사용하는 브라우저 중 94.2%가 고유 지문을 가지고 있었습니다.여기에는 쿠키가 포함되지 않습니다!

상세 정보:

위의 지문 채취는 동작하지만 콜리젼이 발생할 수 있습니다.

1가지 방법은 사용자와의 각 대화 URL에 UID를 추가하는 것입니다.

http://someplace.com/12899823/user/profile

사이트 내의 모든 링크에 이 수식어가 적용됩니다.ASP 방식과 비슷합니다.페이지 간에 FORM 데이터를 사용하여 작업하는 데 사용되는 Net.

에버쿠키에 대해 알아봤어?브라우저 간에 동작하거나 동작하지 않을 수 있습니다.그들의 사이트에서 발췌한거야

"사용자가 한 브라우저에서 요리된 후 다른 브라우저로 전환한 경우 로컬 공유 개체 쿠키가 아직 있는 한 쿠키가 두 브라우저 모두에서 재생됩니다.

캐시된 png을 사용하여 이 작업을 수행할 수 있습니다. 다소 신뢰성이 떨어집니다(브라우저마다 동작이 다르며 사용자가 캐시를 클리어하면 실패합니다). 하지만 이것은 옵션입니다.

1: 하나의 사용자 ID를 16진수 문자열로 저장하는 데이터베이스 설정

2: 사용자 ID를 생성하여 DB에 저장한 후 해당 16진수 문자열 값(각 픽셀은 4바이트)에서 진정한 색상의 .png을 생성하여 브라우저에 반환합니다.content-type 헤더와 캐시 헤더를 반드시 설정해 주세요.

에서 3: HTML JS의 이미지를 .<img id='user_id' src='genUser.php' />

캔버스에 . 4: 캔버스에 그림을 그립니다.ctx.drawImage(document.getElementById('user_id'), 0, 0);

이 를 5로 .ctx.getImageData열여섯 살

6: 사용자 컴퓨터에 캐시된 고유 사용자 ID입니다.

에태그로도 할 수 있어요.많은 소송들이 제기되었기 때문에 이것이 합법적이었는지는 확실하지 않지만.

사용자에게 올바르게 경고하거나 인트라넷 웹 사이트와 같은 것이 있으면 문제가 없을 수 있습니다.

디바이스 ID를 저장하는 BLOB를 생성할 수 있습니다.

단점은 브라우저가 파일을 직접 저장하기 위해 파일 시스템에 액세스할 수 없기 때문에 사용자가 BLOB를 다운로드해야 한다는 것입니다(다운로드 강제 실행 가능).

참조:

https://www.inkling.com/read/javascript-definitive-guide-david-flanagan-6th/chapter-22/blobs

당신이 말한 것에 근거해:

기본적으로는 사용자가 아닌 디바이스 인식을 원합니다.

가장 좋은 방법은 NIC ID인 MAC 주소를 보내는 것입니다.

PHP에서 접속된 클라이언트의 MAC IP 주소를 취득하려면 어떻게 해야 합니다.

비효율적이지만 원하는 결과를 얻을 수 있는 경우 API를 폴링할 수 있습니다.일정 간격으로 사용자 데이터를 전송하는 백그라운드 프로세스를 클라이언트 측에 배치합니다.API로 전송하려면 사용자 식별자가 필요합니다.이 정보가 있으면 해당 고유 식별자와 관련된 정보를 함께 전송할 수 있습니다.

따라서 쿠키 및 로컬 저장소가 필요하지 않습니다.

믿을 수 없어, http://browserspy.dk는 아직 여기에 언급되지 않았어!이 사이트에서는 분류자를 작성하는 데 사용할 수 있는 많은 기능(패턴 인식)을 설명하고 있습니다.

그리고 그 기능을 평가하기 위해서는 특히 Support Vector Machine과 libsvm을 권장합니다.

세션 중 또는 세션 간에 추적하시겠습니까?

사이트가 HTTPS Everywhere인 경우 TLS 세션 ID를 사용하여 사용자의 세션을 추적할 수 있습니다.

  1. 크로스 플랫폼 더미(nsapi)를 생성하여 사용자가 플러그인 이름 또는 버전을 다운로드할 때(로그인 후 등) 고유한 이름을 생성합니다.
  2. 플러그인 설치 제공/정책별로 설치

이를 위해서는 사용자가 자발적으로 ID를 설치해야 합니다.

플러그인이 인스톨 되면, 브라우저의 핑거 프린트에 이 플러그인이 포함됩니다.정보를 서버로 되돌리려면 클라이언트 측에서 플러그인을 효과적으로 감지하는 알고리즘이 필요합니다. 그렇지 않으면 IE 및 Firefox > = 28 사용자가 유효한 식별자 표가 필요합니다.

이를 위해서는 브라우저 공급업체에 의해 폐쇄될 가능성이 높은 기술에 대한 비교적 높은 투자가 필요합니다.사용자에게 플러그인을 설치하도록 설득할 수 있는 경우 로컬프록시 설치, VPN 사용 또는 네트워크 드라이버 패치 적용 등의 옵션을 사용할 수도 있습니다.

식별을 원하지 않는 사용자(또는 시스템)는 항상 이를 방지하는 방법을 찾을 수 있습니다.

언급URL : https://stackoverflow.com/questions/15966812/user-recognition-without-cookies-or-local-storage