MTvote でアクセス制限&投票データのクリア

| コメント(0) | トラックバック(0)

MTvoteを付けたのは良いのだけれど、 なんだかよくわからない記事にたくさん投票されてます。 アクセスログを見てみると、 どうもクローラー(ボット)からのアクセスが大半らしい・・・

これでは正しい集計ができないので、対策をとってみましょう。 ついでに、 同じ人が同じ記事に一度に何度も投票できないような制限を、 非常に単純な仕掛けでかけてみます。

改造内容はこんな感じにします。

  • Google、 Yahoo!、 MSN、 Baidu からのクローラーをアクセス制限
  • 同一IPアドレスから同一Entryへの連続投票を制限

すごく手抜きなので、制限事項は下記以外にもたくさんありますw

  • IPアドレスとEntry_IDはサーバーで一つしか保持していないので、Aユーザが2回連続投票する間にBユーザが投票してしまうと、Aユーザは連続投票できてしまう。
  • 保存ファイルにロックをかけていない(タイミングによっては壊れてしまうかも)
  • FORMはGETのみ(POSTに対応させてません)

ほかにもいろいろありますが、ご勘弁を。 まぁ、 使えそうだからいいかな~。

FORMの記述と改造内容は下記のとおり。 なお、下記をもとに改修を行ったことによる如何なる損害についても、 ワタシは責任を負わないものといたしますw。

まずはFORMのほうから。 個別記事のテンプレートに下記のような設定を追加しています。

Bad ← <a href="<$MTCGIPath$>mt-vote.cgi?__mode=vote&entry_id=<$MTEntryID$>&value=1"> 1 </a>
 <a href="<$MTCGIPath$>mt-vote.cgi?__mode=vote&entry_id=<$MTEntryID$>&value=2"> 2 </a>
 <a href="<$MTCGIPath$>mt-vote.cgi?__mode=vote&entry_id=<$MTEntryID$>&value=3"> 3 </a>
 <a href="<$MTCGIPath$>mt-vote.cgi?__mode=vote&entry_id=<$MTEntryID$>&value=4"> 4 </a>
 <a href="<$MTCGIPath$>mt-vote.cgi?__mode=vote&entry_id=<$MTEntryID$>&value=5"> 5 </a>
 → Good    平均点:(<MTVoteAverage lastn="300">) 総合点:(<MTVoteTotalValue>) 投票人数:(<MTVoteNumber>)<br />

次に MTVote の改造です。 今回は、 mt-vote.cgi のみの改修となります。 通常は、 $MT_DIR/plugin/ に入れてあるはずです。 内容は下記のとおり。 太字のところが追加になります。

#!/usr/bin/perl -w

use strict;

my($MT_DIR);
BEGIN {
  if ($0 =~ m!(.*[/\\])!) {
    $MT_DIR = $1;
  } else {
    $MT_DIR = './';
  }
  unshift @INC, $MT_DIR . 'lib';
  unshift @INC, $MT_DIR . 'extlib';
}


# エラー表示関数
sub error()
{
  print "Content-Type: text/html\n\n";
  print "<html><head>\n";
  print '<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">';
  print "</head><body>\n";
  print "<strong>$_[0]</strong><br />\n";
  print "</body></html>\n";
  exit;
}

# 前回のIPアドレスとENTRY_IDをファイルから読み込み
my $mtvote_check="./mt-votechk.dat";
open(IN,"$mtvote_check") || &error("Open Error $mtvote_check");
my $rdata = <IN>;
my ($ipaddr, $entry_id) = split(/:/, $rdata);
close(IN);

# 主要なBOTを排除
my $uagent = $ENV{'HTTP_USER_AGENT'};
if (($uagent =~ /Googlebot/)||($uagent =~ /Slurp/)||($uagent =~ /msnbot/)||($uagent =~ /Baidu/)){
  &error("access denied");
}

# FORMからの引数(IPアドレスとENTRY_ID)を取得
my %QUERY;
my $qdata = $ENV{'QUERY_STRING'};
my @qdatas = split(/&/, $qdata);
foreach my $pair (@qdatas) {
  $qdata =~ tr/+/ /;
  $qdata =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('H2', $1)/eg;
  my ($qname, $qvalue) = split(/=/, $pair);
  $QUERY{$qname} = $qvalue;
}

#ひとつ前とIPアドレス、ENTRY_IDが同じだった場合
if (($ENV{'REMOTE_ADDR'} eq $ipaddr) && ($QUERY{"entry_id"} == $entry_id)) {
  &error("すでに投票いただいております。ブラウザの戻るを押してください");
}

# 今回のIPアドレスとENTRY_IDをファイルへ保存
open(OUT,">$mtvote_check") || &error("Write Error $mtvote_check");
print OUT "$ENV{'REMOTE_ADDR'}:$QUERY{'entry_id'}";
close(OUT);

eval {
  require MT::App::Vote;
  my $app = MT::App::Vote->new ( Config => $MT_DIR . 'mt.cfg',
     Directory => $MT_DIR )
     or die MT::App::Vote->errstr;
  local $SIG{__WARN__} = sub { $app->trace ($_[0]) };
  $app->run;
};

if ($@) {
  print "Content-Type: text/html\n\n";
  print "An error occurred: $@";
}

次にデータ保存用のファイルを作ります。 Windows では Explorer で新規にテキストファイルを作成し、 名前を mt-votechk.dat にします。 このファイルを、 mt-vote.cgi と同じディレクトリに FTP でアップロードし、 ファイル属性を 0666 に変更します。

最後に、 個別の記事を再構築してあげれば完成です。


これに伴いまして、 MTvote を付け始めてからの投票情報をいったんすべてクリアしました。
削除の仕方はデータベースによって異なると思いますが、 MySQL の場合はこんな感じです。

まず、 phpMyAdmin を起動して、 mt_plugindata テーブルを選択します。 検索タブをクリックし実行ボタンを押してテーブルのレコード一覧を表示させます。 plugindata_plugin の列が 'MTVotingSystem' となっているものをすべてチェックし、 一括削除します。 これでデータがクリアされました。 記事を再構築すればマッサラな状態から集計が始ります。


まだあまり検証できてないので、気づいた点があればご連絡ください^^。

この記事はどうでしたか?

ちょっと時間かかりますが、よかったらポチッとしてください^^。
もしエラーになっても、リロードしないでね~w(このページの結果はすぐに反映されません)
Bad ←          → Good    平均点:(3.4) 総合点:(373) 投票人数:(109)

トラックバック(0)

トラックバックURL:

 

コメントする

カテゴリ

アーカイブ

人気ブログランキング - よんだりくわんだり
Powered by Movable Type 4.261
Counter
本日: today 昨日: アクセス一覧

お買い物




楽天で探す



マクロミルへ登録

広告

デル株式会社 宅配ピザのドミノ・ピザ セブンネットショッピング

Blog pet

このブログ記事について

このページは、chikaが2009年3月28日 00:09に書いたブログ記事です。

ひとつ前のブログ記事は「今年はクリスタル」です。

次のブログ記事は「ドミノピザのマグカップ」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。