Referer(リンク元の追跡)

Referer(リンク元の追跡)

誰に聞いて、このページまでたどり着けたのでしょうか?

RFC2616 のヘッダフィールドの定義 で定義されているRefererヘッダを 利用するとリンク元の追跡が可能となります。

  • 逆リンクの生成
    1. 興味
    2. ログの取得
    3. キャッシュの活用 等のためにある。
  • 保守のため
    1. リンクやミスタイプ(typo)のリンクを追跡 できるようにもする。

ということなので、ここで保持した内容が、必ずしも有用な情報となるとは限らない。 また、セキュリティ上、 リンクソースがプライベートとなるような情報(イントラネットなど)、 または他のプライベート情報を拾ってしまう場合もあり得るので、 これを実装すると、公開してしまう恐れもある。

  • 似た内容として、TrackBack(攻撃元の追跡) がある。

Refererこの場合は、ブラウザが語ってくれたヘッダを信じ、ここにたどり着く前に、どこで道草をしていたのか?が分かります。勝手にリンク元の追跡を行うところが TrackBack とは異なります。
TrackBack私は、貴方のページに対してリンクしていますよ!という通知に従い、その情報を保持します。Referer とは違い、明示的に通知された内容のみ保持します。また、明示的に通知します。

なぜ?

official:質問箱のリンク元の表示から、このページを 起こしました。 また、実装する上で、みなさんが、これも注意しなきゃいけないのでは?といった 懸念事項などがあれば、事前に洗い出し、実装しておきたかった。 ということにあります。

PukiWiki での実装

ページを表示する際に、Referer ヘッダが付いているかどうか判定して、 付いている場合には、TrackBack と同様な処理イメージで保存する。 という流れであれば、すごく簡単に実装できると考えています。

アクセス解析

今、考えている実装だと、ページ毎に解析を行うことになりますから、 それを統合して表示したり、加工次第では、色々と解析できると考えています。

保有項目

  • Referer ヘッダ内容
  • 参照カウンタ(単にインクリメント)
  • 初回登録日時
  • 最終更新日時

懸案事項

  • Referer を詐称した場合の取り扱うについて、どこまでチェックするか?

    チェックを入れるのは簡単ですが、処理時間がかかります。

    • 今回は、URI として正しいか?までは入れようと考えていますが、
    • その URI について HEAD して、存在確認までは行わないのかなぁ?です。
  • データ保守

    Referer を管理するデータが陳腐化してきた場合の保守については、 TrackBack 同様に、保守プラグインでも別途作ってという逃げでと 考えています。なので、初期開発時は棚上げしておきます。 というのも、さほどの難易度ではないと考えておりますもので。

参考リンク

PukiWiki でのセットアップ

  • :config/plugin/referer/config
    *COLOR
    一覧表示時の表ヘッダー項目の表示色を定義する。未定義時は、デフォルトとして
    以下の色が採用される。"cur"は、選択項目色。"etc"は、その他項目色。
    |cur|BGCOLOR(#88ff88)|
    |etc|BGCOLOR(#cccccc)|
    
    *IGNORE
    無視したい URI を定義する。
    |http://localhost|

ご意見

  • Referer spamというものがあるそうです。Refererにアクセスして欲しいURLを設定して無差別アクセスするもののようです。Refererの記録時あるいは閲覧時になんらかのフィルタリング機能が必要かも。 -- mss? 2003-06-15 (日) 18:59:11
    • そういった事実も把握するのであれば、登録時には迂回せず、閲覧時にフィルタリングを適用するという流れが良いのでしょうかね?いずれにしても、フィルタの登録したタイミングによって意図しないデータが存在するのも事実ですから、閲覧時にゴミを除去するのは必須なのかなぁ?というところからです。-- upk 2003-06-15 (日) 23:33:02
  • 個人サイトで、それに遇っていますが、正規のものと区別がつきにくく、フィルタリングはなかなか難しいです。 -- maja 2003-06-15 (日) 19:23:12
    • フィルタリングをやるとすれば :config で登録してという流れなのでしょうけど、実際には、2種類ある(ALLOW、DENY)と思いますが、:config に登録されていたら、[登録する|登録しない]のどっちが便利でしょうかね?2つやるのも手ではありますが、そこまで必要とは思えないもので。まぁ、駄目を把握するのと、OKを把握するのは、どっちが楽か?なんですけどね。-- upk 2003-06-15 (日) 20:03:48
    • 一見して判断できないとなると、申告制のイメージで、DENY が良いのかなぁ? -- upk 2003-06-15 (日) 23:43:01
  • これですね。アダルトサイトがRefererとして自サイトのURLを送出して宣伝しているらしい。えび日記 -- reimy 2003-06-16 (月) 23:22:51
    • この宣伝手法をTrackBackでやるのが流行りそう。-- reimy 2003-06-16 (月) 23:24:21
      • Referer は、GET でOKですけど、TrackBack は、POST なので、気持ち難易度があがるものの。Referer よりも面倒なのは事実ですね。適当にやって、数打っても当たりませんからね。-- upk 2003-06-17 (火) 01:51:55
  • 開発日記/2003-07-03で本体に取り込まれたようですので、ちょっと見させてもらいました。一点だけ気になる点があります。それは保存ファイルを md5() を使って取得している点です。これだと、ファイル名からページ名へのマッピングが簡単に取れなくなってしまうので、wiki/ などと同様に encode() を使ったファイル名を使いませんか? -- masao 2003-07-03 (木) 18:04:40
    • TrackBack を流用(リンクということで)し、データもそこに保存するので、同じ体系にしました。なぜ、md5() にしたのか?ということですけど、TrackBack ID は、ぱっと整数が良かろうが、いまさら、ページ毎に見た目だけで採番するのもと考えて、一意な長さになる方法にしました。(とはいっても、encode()だと、すごく長くなるもんで、ちょっと ID とは言えないなぁ。ということだけですけどね。)ページ数が多くなると問題だとは認識しつつも、tb_id2page() という関数は既に用意したりしています。現在の利用だと、指摘された引き方が無いので、今後という観点で、データからページ名を取得するというニーズって、そんなにありますかね?というところなのですが... 遅くなりつつも、逆引きはできるようにはしていますし。どうでしょうか?-- upk 2003-07-03 (木) 19:13:10
    • というよりも、データの移行などを考えると、他のwiki,cacheなどでのデータ形式と合わせてもらえると、PukiWiki(PHP)を介さずにファイルを扱えるので便利なんですが、どうでしょうか? -- masao 2003-07-04 (金) 12:28:54
      • そうだと、もっと理解できませんよぉ。PHPを介さずに、いまの状態でも OK だと思いますけども。PukiWiki からみれば新機能なので、修正するとかではなく、整理という観点でお聞きしたいんですがどう移行したいという、もっと具体的な作業イメージも含めて教えていただけませんか?-- upk 2003-07-04 (金) 12:54:29
      • うまく伝えられないですみません。例えば、「ソフトウェア/*」というページ階層の下のファイルの中身を一括処理して、別のWikiなりに移行したいという要求があった場合などです。encode() が使ってあれば、ファイル名を wiki/A5BDA5D5A5C8A5A6A5A7A5A2*.txt として、シェルからそのまま指定できますが、Referer のデータファイル名が md5() だとこういった指定ができません。 -- masao 2003-07-04 (金) 13:45:41
      • 相手側リンクに対するデータを、URIの変更が無いという前提で、このような移行って現実的なのでしょうかね? -- upk 2003-07-04 (金) 18:04:42
      • 「移行」はあまり現実的でない例かもしれませんが、「指定」して「一括処理」は現実的なんじゃないかなあ。私は既存のHTMLを変換してwikiに取り込んだ際にそういう指定を使ったので、それができないという点でmd5()には違和感を覚えます。 -- masao 2003-07-05 (土) 16:29:19
      • ./wiki/ な文書じゃないのですから違和感があってもおかしくはない。と考えています。重要なのは、このデータは、どいう性質のデータなのか?だからどう扱い、どう管理していくのか?だと理解しています。-- upk 2003-07-05 (土) 22:50:46
      • TrackBack の流用ありきでいたので、逆にTrackBack を流用しないという前提で考えるべきであり、そうなると encode() 化妥当だと思います。また、キャッシュにデータを保存するように設計したと思います。なので、encode() に変更するのであれば、そこまで変えないと、中途半端だなぁ。です。ここだけ encode() にして欲しいだと逆に違和感があります。意味合い的にはリンク情報の管理ということで同類とし、だから流用もおかしくはなかろうというところです。ということで、encode() でどうしても。というのであれば、この実装はふさわしいものではない。ということだと思います。-- upk 2003-07-05 (土) 22:14:59
      • なので、感覚的なことで云々ではなく、私が想定していた範囲外のところで、どう問題になってくるのかなぁ?ということがあるのであれば聞いて、こういった流用を排除して、分離すべきかも含めて、整理したかったんですけどね。-- upk 2003-07-05 (土) 22:25:29
      • なるほど。私は $referer = 1; $trackback=0; で使う予定(TrackBackを使う予定はない)で、その運用が前提にあったために、こういう感覚の違いになったのでしょうね。 -- masao 2003-07-07 (月) 15:36:46
  • ついでにもう一点。こっちはスキンの話かもしれませんが、Refererも$relatedみたいな表示方法にして、先頭のN件だけそのページ内からリンクを張って、残りを plugin=referer へのリンクという形式で表示させませんか?(tDiary風) メニュー項目がちょっと多すぎるように感じるので。。。 -- masao 2003-07-04 (金) 14:11:16
    • 本分下の方にN件分を表示したいというイメージですかね?これだと、プラグインとしての挙動ではなくなるんだと思いますが、何か良い方法ってあるのかなぁ? -- upk 2003-07-04 (金) 18:04:42
    • ちょっと強引な手ですが、スキンの中でプラグインを呼び出すこともできるので、必要な人は、スキン内の適当な所へ<?php echo convert_html("#referer"); ?>と書いてもらうとか。私はこの方法でカウンター表示させてます。--龍司 2003-07-04 (金) 20:18:56
    • なるほど。とりあえず↓な感じでしのぐことにします。--masao2003-07-05 (土) 16:55:43
      diff -u -b -r1.1 referer.inc.php
      --- plugin/referer.inc.php	3 Jul 2003 04:56:04 -0000	1.1
      +++ plugin/referer.inc.php	5 Jul 2003 07:52:50 -0000
      @@ -9,6 +9,34 @@
       // 構成定義ファイル
       define('CONFIG_REFERER','plugin/referer/config');
       
      +function plugin_referer_convert() {
      +  global $script,$vars;
      +  $args = func_get_args();
      +
      +  $num = is_numeric($args[0]) ? $args[0] : 0;
      +
      +  $page = (is_null($args[1]) || empty($args[1])) ? $vars['page'] : $args[1];
      +  $r_page = rawurlencode($page);
      +
      +  $file   = TRACKBACK_DIR.md5(rawurlencode($page)).".ref";
      +  $data = tb_get($file);
      +  usort($data, 'referer_sort_by_Counter_d');  // 2d カウンタ(大きい順)
      +  $result = "<div class=\"referer\">リンク元 |";
      +  $i = 0;
      +  foreach ($data as $x) {
      +    if ($num != 0 && $num == $i) {
      +      $result .= " <a href=\"$script?plugin=referer&amp;page=$r_page\">...</a>";
      +      break;
      +    }
      +    $count = htmlspecialchars($x[2]);
      +    $url = htmlspecialchars(rawurldecode($x[3])); // URL
      +    $result .= "<a href=\"$url\">$count</a>|";
      +    $i++;
      +  }
      +  $result .= "</div>\n";
      +  return $result;
      +}
      +
       function plugin_referer_action() {
         global $script,$vars,$post,$referer;
         global $_referer_msg;
      
      diff -u -b -r1.26 pukiwiki.skin.ja.php
      --- skin/pukiwiki.skin.ja.php	2 Jul 2003 14:53:44 -0000	1.26
      +++ skin/pukiwiki.skin.ja.php	5 Jul 2003 07:52:50 -0000
      @@ -91,12 +91,6 @@
        [ <a href="<?php echo "$script?plugin=tb&amp;__mode=view&amp;tb_id=$tb_id" ?>"
        onclick="OpenTrackback(this.href); return false">TrackBack(<?php echo tb_count($r_page) ?>)</a> ]
       <?php } ?>
       
      -<?php
      -  if ($referer) {
      -?>
      - [ <a href="<?php echo "$script?plugin=referer&amp;page=$r_page" ?>">リンク元</a> ]
      -<?php } ?>
      -
       </div>
       <?php echo $hr ?>
       
      @@ -178,6 +172,11 @@
       </div>
       <?php } ?>
       
      +<?php
      +if ($referer) {
      +  echo convert_html("#referer(20)");
      +}
      +?>
       
       <div id="footer">
        Modified by <a href="<?php echo $modifierlink ?>"><?php echo $modifier ?></a>
  • 個人の趣味と言われればお終いなのですが、
    usort($data, 'referer_sort_by_Counter_d');  // 2d カウンタ(大きい順)
    なもんでしょうかね?本来、N件表示であれば、それは時系列的な流れから、素直に直近の飛来順表示かなぁ?と思います。ある時点において、リンクしてくれていたサイトが、人気サイトで、カウンタをあげてくれたとしても、そのサイトが消滅していたりすると、その表示順は、意味がなくなる日がきます。そういう考慮をすると、それは、単に、直近の飛来順なのだろうと思います。なので、私がそのロジックを組むと、デフォルトは、直近に飛んできた順(最終更新日順)でソートすると思います。-- upk 2003-07-06 (日) 18:59:59
    • そのあたりが tDiary 風といった由縁でしょうか…。 直近のRefererを知りたい場合は plugin=referer を見ればいいかなあと思ってました。 -- masao 2003-07-07 (月) 15:39:47
  • どういう挙動をするのが正しいんでしょう…。[リンク元]とは出たのですが…。 -- maja 2003-07-06 (日) 10:24:20
    • 設定した時点では、ただリンクが表示されているだけで、何のアクションもありません。-- upk 2003-07-06 (日) 18:37:34
      • 自サイト内でのRefererは、保存を迂回するようになっていますらか、実際には、どこかのサイトから、そのページに飛んできた時しか、Refererの値を保存しないようになっています。設定を変更したからと言って、即座に、誰かが飛んできてくれているのなら、良いのですが、そうでなければ、ただ表示されているだけです。-- upk 2003-07-06 (日) 13:47:27
      • また、データがある時だけ、そのアンカーを有効にするも考えましたが、そうなると、処理が重くなって、実際に表示する場合と同じ処理に近いものをやらないと、判定できない。ということで、端折りました。^_^; -- upk 2003-07-06 (日) 13:47:27
      • TrackBack は、データを数えるだけなのですが、この Referer だと、SPAM対策の関係で、:config データを読み込んだ上に、保存されているデータの1つ1つを判定して、有効個数が分かる。ということです。見出しを表示するだけで、この Referer の内容が見たいとも限らない。という状態でのサービス機能となるこの処理は、ちょっと重いだろうなぁ?と考え止めました。-- upk 2003-07-06 (日) 13:50:45
  • 上のパッチ、ぱっと見、OKそうだったんですが、SPAM対策してないんですね。 -- upk 2003-07-06 (日) 14:07:46
    • 上のパッチもSPAM対応すると、foreach で、対象データが何も無くなる場合があるので、その分、面倒になってきます。でも、前にも書きましたが、その SPAM データの登録されるタイミングと、除外設定を登録したタイミングの関係で、結局、表示する直前で再度判定しないと意味が無いので、たとえ、データそのものから除外していたとしても、やっぱりこの処理はつきまとってくれます。であればということで、統計的な利用も考慮して、あえてデータを残すようにしています。(意図して削除処理を入れていないんです。内部的には消せるようなフラグも持っているのにです。) -- upk 2003-07-06 (日) 18:47:26
    • はい。3分ハッキングということでサボっちゃいました。:) 確かに foreach の中で判別したほうが良いですね。 -- masao 2003-07-07 (月) 15:49:12
  • Tikiでは、リンク元ではなく参照元と表現しているんですねぇ。あと、Referer データが無い場合には、
    No registered referer exists
    と表示している。どっちが違和感が無いでしょうかね?ということと、わざわざ、データが無いよ!と画面を遷移させるのって、どうだろう?なのです。何も遷移しないから、逆に、どういった挙動なんですか?という質問があるのも、事実とは思います。-- upk 2003-07-06 (日) 19:58:49
    • どこかに簡単なものでも説明があれば良かったのですが、無かったので、「どういう挙動」と質問させていただきました。PukiWiki全体に関して、まだまだマニュアルを充実させるべきかと思います。ページの遷移は正直どちらでも良いと思います。 -- maja 2003-07-07 (月) 21:32:31
  • 7/30版CVSでrefererをいれると更新後に真っ白な画面になる(更新はされている)という現象が出ています。pukiwiki.ini.phpでは、編集などの制限は値はせっていしてありますが、On/Offフラグは0です。 http://tec-tech.org/test/ に CVS(7/30)のpukiwiki.ini.phpとFrontPageだけ変えたものを置いてあります -- merlin 2003-07-31 (木) 22:08:24
    • 見に行きましたが、普通に動いていました。なので、何がかなぁ?という感じです。-- upk 2003-07-31 (木) 23:01:18
    • うーん そうすると mozilla1.2の問題かなぁ? Frontpageを編集して保存すると真っ白画面がいったん出るんです。サーバ上ではファイルは更新されているんですが.. -- merlin 2003-08-01 (金) 05:07:50

関連ページ


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2009-08-25 (火) 12:42:54
Site admin: PukiWiki Development Team

PukiWiki 1.5.2+ © 2001-2019 PukiWiki Development Team. Powered by PHP 5.6.40-0+deb8u1. HTML convert time: 0.601 sec.

OSDN