jjzjj

javascript - 无需 cookie 或本地存储的用户识别

coder 2023-04-24 原文

我正在构建一个分析工具,我目前可以从他们的用户代理获取用户的 IP 地址、浏览器和操作系统。

我想知道是否有可能在不使用 cookie 或本地存储的情况下检测到同一用户?我不期待这里的代码示例;只是一个简单的提示,告诉你在哪里可以看得更远。

忘了提到如果它是同一台计算机/设备,它需要跨浏览器兼容。基本上我在设备识别之后并不是真正的用户。

最佳答案

简介

如果我理解正确,您需要确定没有唯一标识符的用户,因此您想通过匹配随机数据来确定他们是谁。您无法可靠地存储用户的身份,因为:

  • Cookie 可以删除
  • IP地址可以更改
  • 浏览器可以更改
  • 浏览器缓存可能被删除

  • Java Applet 或 Com Object 本来是使用硬件信息散列的简单解决方案,但是现在人们非常关注安全性,很难让人们在他们的系统上安装这些类型的程序。这让您不得不使用 Cookie 和其他类似工具。

    Cookie 和其他类似工具

    您可能会考虑构建数据配置文件,然后使用概率测试来识别可能的用户。可以通过以下某种组合生成对此有用的配置文件:
  • IP地址
  • 真实IP地址
  • 代理IP地址(用户经常重复使用同一个代理)
  • cookies
  • HTTP Cookie
  • session Cookie
  • 第 3 方 Cookie
  • Flash Cookies ( most people don't know how to delete these )
  • 网络错误(不太可靠,因为错误得到修复,但仍然有用)
  • PDF 错误
  • 闪存错误
  • Java 错误
  • 浏览器
  • 点击跟踪(许多用户在每次访问时访问同一系列的页面)
  • 浏览器指纹
    - 已安装的插件(人们经常有各种各样的、有点独特的插件集)
  • 缓存图像(人们有时会删除他们的 cookie 但保留缓存图像)
  • 使用 Blob
  • URL(浏览器历史记录或 cookie 可能在 URL 中包含唯一的用户 ID,例如 https://stackoverflow.com/users/1226894http://www.facebook.com/barackobama?fref=ts)
  • System Fonts Detection (这是一个鲜为人知但通常是唯一的键签名)
  • HTML5 和 JavaScript
  • HTML5 LocalStorage
  • HTML5 地理定位 API 和反向地理编码
  • 体系结构、操作系统语言、系统时间、屏幕分辨率等
  • 网络信息API
  • 电池状态API

  • 当然,我列出的项目只是可以唯一标识用户的几种可能方式。还有更多。

    使用这组随机数据元素构建数据配置文件,下一步是什么?

    下一步是开发一些Fuzzy Logic ,或者更好的是 Artificial Neural Network (使用模糊逻辑)。无论哪种情况,我们的想法都是训练您的系统,然后将其训练与 Bayesian Inference 结合起来。以提高结果的准确性。



    NeuralMesh PHP 库允许您生成人工神经网络。要实现贝叶斯推理,请查看以下链接:
  • Implement Bayesian inference using PHP, Part 1
  • Implement Bayesian inference using PHP, Part 2
  • Implement Bayesian inference using PHP, Part 3

  • 这时候,你可能会想:

    为什么对于一个看似简单的任务需要如此多的数学和逻辑?

    基本上,因为这不是一项简单的任务。实际上,您要实现的是纯概率。例如,给定以下已知用户:
    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 的概率是多少?这两场比赛中哪一场最有可能?

    为了有效回答这个问题,您需要了解Frequency vs Probability Format为什么Joint Probability可能是更好的方法。这里的细节太多了(这就是我给你链接的原因),但一个很好的例子是 Medical Diagnosis Wizard Application ,它使用症状的组合来识别可能的疾病。

    想一想包含您的数据配置文件(上例中的 B + C + E + G + F + K)的一系列数据点作为症状,将未知用户作为疾病。通过识别疾病,您可以进一步确定合适的治疗方法(将此用户视为 User1)。

    显然,我们已识别出超过 1 个症状的疾病更容易识别。事实上,我们能识别的症状越多,我们的诊断就越容易和准确。

    还有其他选择吗?

    当然。作为替代措施,您可以创建自己的简单评分算法,并基于完全匹​​配。这不如概率有效,但对您来说可能更容易实现。

    例如,考虑这个简单的分数图表:
    +-------------------------+--------+------------+
    |        Property         | Weight | Importance |
    +-------------------------+--------+------------+
    | Real IP address         |     60 |          5 |
    | Used proxy IP address   |     40 |          4 |
    | HTTP Cookies            |     80 |          8 |
    | Session Cookies         |     80 |          6 |
    | 3rd Party Cookies       |     60 |          4 |
    | Flash Cookies           |     90 |          7 |
    | PDF Bug                 |     20 |          1 |
    | Flash Bug               |     20 |          1 |
    | Java Bug                |     20 |          1 |
    | Frequent Pages          |     40 |          1 |
    | Browsers Finger Print   |     35 |          2 |
    | Installed Plugins       |     25 |          1 |
    | Cached Images           |     40 |          3 |
    | URL                     |     60 |          4 |
    | System Fonts Detection  |     70 |          4 |
    | Localstorage            |     90 |          8 |
    | Geolocation             |     70 |          6 |
    | AOLTR                   |     70 |          4 |
    | Network Information API |     40 |          3 |
    | Battery Status API      |     20 |          1 |
    +-------------------------+--------+------------+
    

    For each piece of information which you can gather on a given request, award the associated score, then use Importance to resolve conflicts when scores are the same.

    Proof of Concept

    For a simple proof of concept, please take a look at Perceptron. Perceptron is a RNA Model that is generally used in pattern recognition applications. There is even an old PHP Class which implements it perfectly, but you would likely need to modify it for your purposes.

    Despite being a great tool, Perceptron can still return multiple results (possible matches), so using a Score and Difference comparison is still useful to identify the best of those matches.

    Assumptions

    • Store all possible information about each user (IP, cookies, etc.)
    • Where result is an exact match, increase score by 1
    • Where result is not an exact match, decrease score by 1

    Expectation

    1. Generate RNA labels
    2. Generate random users emulating a database
    3. Generate a single Unknown user
    4. Generate Unknown user RNA and Values
    5. The system will merge RNA information and teach the Perceptron
    6. After training the Perceptron, the system will have a set of weightings
    7. You can now test the Unknown user's pattern and the Perceptron will produce a result set.
    8. Store all Positive matches
    9. Sort the matches first by Score, then by Difference (as described above)
    10. Output the two closest matches, or, if no matches are found, output empty results

    Code for Proof of Concept

    $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 ";
    }
    

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

    “D”的打印_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 您将能够看到 Input (Sensor & Desired), Initial Weights, Output (Sensor, Sum, Network), Error, Correction and Final Weights .
    +----+----+----+----+----+----+----+----+----+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+------+-----+----+---------+---------+---------+---------+---------+---------+---------+---------+---------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----+----+----+----+----+----+----+----+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----------+
    | 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 ++;
    }
    

    这是一个 online demo

    使用的类:
    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
    

    结论

    在没有唯一标识符的情况下识别用户不是一项直接或简单的任务。它依赖于收集足够数量的随机数据,您可以通过各种方法从用户那里收集到这些数据。

    即使您选择不使用人工神经网络,我建议至少使用具有优先级和可能性的简单概率矩阵 - 我希望上面提供的代码和示例足以让您继续下去。

    关于javascript - 无需 cookie 或本地存储的用户识别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15966812/

    有关javascript - 无需 cookie 或本地存储的用户识别的更多相关文章

    1. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

      我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

    2. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

      我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

    3. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

      我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

    4. ruby - 是否可以覆盖 gemfile 进行本地开发? - 2

      我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI

    5. jquery - 我的 jquery AJAX POST 请求无需发送 Authenticity Token (Rails) - 2

      rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送

    6. ruby-on-rails - 简单的 Ruby on Rails 问题——如何将评论附加到用户和文章? - 2

      我意识到这可能是一个非常基本的问题,但我现在已经花了几天时间回过头来解决这个问题,但出于某种原因,Google就是没有帮助我。(我认为部分问题在于我是一个初学者,我不知道该问什么......)我也看过O'Reilly的RubyCookbook和RailsAPI,但我仍然停留在这个问题上.我找到了一些关于多态关系的信息,但它似乎不是我需要的(尽管如果我错了请告诉我)。我正在尝试调整MichaelHartl'stutorial创建一个包含用户、文章和评论的博客应用程序(不使用脚手架)。我希望评论既属于用户又属于文章。我的主要问题是:我不知道如何将当前文章的ID放入评论Controller。

    7. ruby - RVM "ERROR: Unable to checkout branch ."单用户 - 2

      我在新的Debian6VirtualBoxVM上安装RVM时遇到问题。我已经安装了所有需要的包并使用下载了安装脚本(curl-shttps://rvm.beginrescueend.com/install/rvm)>rvm,但以单个用户身份运行时bashrvm我收到以下错误消息:ERROR:Unabletocheckoutbranch.安装在这里停止,并且(据我所知)没有安装RVM的任何文件。如果我以root身份运行脚本(对于多用户安装),我会收到另一条消息:Successfullycheckedoutbranch''安装程序继续并指示成功,但未添加.rvm目录,甚至在修改我的.bas

    8. 报告回顾丨模型进化狂飙,DetectGPT能否识别最新模型生成结果? - 2

      导读语言模型给我们的生产生活带来了极大便利,但同时不少人也利用他们从事作弊工作。如何规避这些难辨真伪的文字所产生的负面影响也成为一大难题。在3月9日智源Live第33期活动「DetectGPT:判断文本是否为机器生成的工具」中,主讲人Eric为我们讲解了DetectGPT工作背后的思路——一种基于概率曲率检测的用于检测模型生成文本的工具,它可以帮助我们更好地分辨文章的来源和可信度,对保护信息真实、防止欺诈等方面具有重要意义。本次报告主要围绕其功能,实现和效果等展开。(文末点击“阅读原文”,查看活动回放。)Ericmitchell斯坦福大学计算机系四年级博士生,由ChelseaFinn和Chri

    9. ruby - Rack:如何将 URL 存储为变量? - 2

      我正在编写一个简单的静态Rack应用程序。查看下面的config.ru代码:useRack::Static,:urls=>["/elements","/img","/pages","/users","/css","/js"],:root=>"archive"map'/'dorunProc.new{|env|[200,{'Content-Type'=>'text/html','Cache-Control'=>'public,max-age=6400'},File.open('archive/splash.html',File::RDONLY)]}endmap'/pages/search.

    10. [Vuforia]二.3D物体识别 - 2

      之前说过10之后的版本没有3dScan了,所以还是9.8的版本或者之前更早的版本。 3d物体扫描需要先下载扫描的APK进行扫面。首先要在手机上装一个扫描程序,扫描现实中的三维物体,然后上传高通官网,在下载成UnityPackage类型让Unity能够使用这个扫描程序可以从高通官网上进行下载,是一个安卓程序。点到Tools往下滑,找到VuforiaObjectScanner下载后解压数据线连接手机,将apk文件拷入手机安装然后刚才解压文件中的Media文件夹打开,两个PDF图打印第一张A4-ObjectScanningTarget.pdf,主要是用来辅助扫描的。好了,接下来就是扫描三维物体。将瓶

    随机推荐