KENT-WEB サポートコーナー 過去ログ [ 0349 ]


記事No: 14939
投稿日: 2016/06/29(Wed) 03:57:26
タイトルWebPatio5.11にID自動生成機能を
ID情報: rick7634
投稿者: RICK
URLhttp://bbs.dojin-rpg-cheat.com/bbs/patio.cgi

Web Patioに2chみたいなIDを自動生成して
名前の隣に表示する機能を付けたいと思い
スレを立てさせていただきました。

よろしくお願いします。


記事No: 14940
投稿日: 2016/06/29(Wed) 14:09:45
タイトルRe: WebPatio5.11にID自動生成機能を
ID情報: hirayama
投稿者: hirayama
URLhttp://shade-search.com/sts/fsw/wiki.cgi

Kentさんの書籍付録版にトリップ機能やID表示機能のある
2ch風の掲示板があるようなので、それを参考にするのが早いのかも知れませんが、
面白そうなので考えてみました。

なりすまし防止のためのID表示ということなら
同じ投稿者は毎回同じIDが表示され、他人がそのIDを表示できないもの
ということになるかと思いますが、いくつか方法があると思います。

(1)IPアドレスと日付を暗号化してIDを表示。
同じ人が別の日に投稿するとIDが変わることになります。
また、同じIPアドレスの投稿者がいると、別人でも同じIDになる可能性もあります。

(2)初回投稿時にランダムな文字列を生成し、これをクッキーに保存し、この文字列を暗号化してIDとする。
別人が同じIPになる確率は減りますが、この場合も端末が変わるとIDが変わることになります。

(3)トリップ機能を利用する。
名前入力欄で#以降の文字列をID生成のためのパスワードとしてクッキーに保存して
投稿時に暗号化してIDとして表示。
同じパスワードを入力すれば投稿端末が変わっても同じIDを表示できる。
クッキーに保存されているので、次回投稿時は名前入力のみでOK。
クッキーの保存期間が切れたら、投稿フォームにその旨表示して再度トリップ用文字列の再入力を求める。
不特定多数の人が利用する端末で投稿する場合は、クッキーをオフにするなどの対策が必要。

いずれにしてもけっこうな改造ボリュームになりそうなので、
(1)の例の手順だけ記すと、

regist.cgiに

sub create_id {
my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
$year += 1900;
$mon += 1;
my $ip = $ENV{'REMOTE_ADDR'};
use Digest::MD5 qw/md5_hex/;

# MD5で生成した文字列が長いので、先頭から10文字だけ取り出す
my $id = substr(md5_hex($ip . $year . sprintf("%02d",$mon) . sprintf("%02d",$mday)),0,10);
return $id;
}

のような関数を追加して、regist.cgiのsub regist内で保存されるログの末尾に
create_id()で得られるidを保存するよう修正。

IDを表示したいテンプレートファイルで、追加したいところに !id! と追加する。

patio.cgiで、sub bbs_list、sub read_log、sub search、sub past_pageなどの
ログ読み込み部分でIDの値も読み込むように修正する。
IDを$idに保存したなら、
$○○ =~ s/!name!/$nam/g;
のような変換部分の近くに
$○○ =~ s/!id!/$id/g;
のような文を追加する。


記事No: 14992
投稿日: 2016/07/09(Sat) 06:19:49
タイトルRe^2: WebPatio5.11にID自動生成機能を
ID情報: rick7634
投稿者: ROCK

いずれにしても一筋縄では行きそうにないですね。
個人的には2番で行きたいのですが結構なボリュームになりますか?


記事No: 14996
投稿日: 2016/07/09(Sat) 18:45:33
タイトルRe^3: WebPatio5.11にID自動生成機能を
ID情報: hirayama
投稿者: hirayama
URLhttp://shade-search.com/sts/fsw/wiki.cgi

> いずれにしても一筋縄では行きそうにないですね。
> 個人的には2番で行きたいのですが結構なボリュームになりますか?

それほど大きな違いはないと思いますが、クッキーがらみで少し面倒になるかもしれません。
(2)の場合、IDを発行する関数は以下のようになると思います。

sub create_id2 {
my ($ck_nam,$ck_eml,$ck_url,$ck_mlo,$salt) = &get_cookie;
if (!$salt) {
my $length = 10;
my @seed = ('a'..'z', 'A'..'Z', 0..9);
$salt = '';
while(length($salt) < $length) {
$salt .= @seed[int rand(scalar @seed)];
}
&set_cookie('SALT',$salt);
}
use Digest::MD5 qw/md5_hex/;

# MD5で生成した文字列が長いので、先頭から10文字だけ取り出す
my $id = substr(md5_hex($salt),0,10);
return $id;
}

ほかは基本的には(1)のケースと同じですが、これだけではクッキーを無効にしているブラウザの場合
毎回IDが変わってしまうので、その場合の対策も必要だと思います。
クッキーが使えない場合、(1)の処理に切り替えるというのも1案です。

問題はクッキーが使えるかどうかをどう判定するかですね。
1回のアクセスだけでは難しそうなので、
フォーム表示時にダミーのクッキーを発行し、投稿ボタンを押した際、そのクッキー値が保存されていたら
使えると判定してcreate_id2を実行し、使えなかったら(1)の処理ということになるかと思います。


記事No: 14998
投稿日: 2016/07/10(Sun) 05:29:26
タイトルRe^4: WebPatio5.11にID自動生成機能を
ID情報: rick7634
投稿者: ROCK

わかりました。以下の処理の記述方法を教えてほしいです。

regist.cgiのsub regist内で保存されるログの末尾にcreate_id()で得られるidを保存するよう修正。

patio.cgiで、sub bbs_list、sub read_log、sub search、sub past_pageなどのログ読み込み部分でIDの値も読み込むように修正する。
IDを$idに保存したなら、
$○○ =~ s/!name!/$nam/g;
のような変換部分の近くに
$○○ =~ s/!id!/$id/g;
のような文を追加する。

よろしくお願いします。


記事No: 14999
投稿日: 2016/07/10(Sun) 16:30:39
タイトルRe^5: WebPatio5.11にID自動生成機能を
ID情報: hirayama
投稿者: hirayama
URLhttp://shade-search.com/sts/fsw/wiki.cgi

>わかりました。以下の処理の記述方法を教えてほしいです。

修正箇所が複数になるので、それぐらいは自分で書けないと
わけわからなくなる恐れがありますが、一応書いておきます。

,諒は、割と簡単で、sub regist の最初の方に

my $id = create_id();

を追加します。そして、新規投稿のスレッド更新処理の
print OUT "0<>$in{sub}<>$name<>$in{email}<>$in{comment}<>$date<>$host<>$pwd<>$in{url}<>$in{mlo}<>$au{id}<>$time<>$ex{1},$w{1},$h{1}<>$ex{2},$w{2},$h{2}<>$ex{3},$w{3},$h{3}<>\n";

print OUT "0<>$in{sub}<>$name<>$in{email}<>$in{comment}<>$date<>$host<>$pwd<>$in{url}<>$in{mlo}<>$au{id}<>$time<>$ex{1},$w{1},$h{1}<>$ex{2},$w{2},$h{2}<>$ex{3},$w{3},$h{3}<>$id<>\n";

返信投稿のスレッド更新処理も
push(@log,"$newno<>$in{sub}<>$name<>$in{email}<>$in{comment}<>$date<>$host<>$pwd<>$in{url}<>$in{mlo}<>$au{id}<>$time<>$ex{1},$w{1},$h{1}<>$ex{2},$w{2},$h{2}<>$ex{3},$w{3},$h{3}<>\n");

push(@log,"$newno<>$in{sub}<>$name<>$in{email}<>$in{comment}<>$date<>$host<>$pwd<>$in{url}<>$in{mlo}<>$au{id}<>$time<>$ex{1},$w{1},$h{1}<>$ex{2},$w{2},$h{2}<>$ex{3},$w{3},$h{3}<>$id<>\n");
と修正します。

regist.cgiには先に記したsub create_idを追加しておく必要があります。(2)の処理を行うなら、さらにsub create_id、sub get_cookie、sub set_cookieも追加します。
sub get_cookieとsub set_cookieはpatio.cgiの分をそのままコピペすればいいです。
以上の修正で投稿時にIDがログに保存されるようになります。

△諒はかなり修正箇所が多いので、修正の手順を記すにとどめます。
まず、tmplディレクトリ内のhtmlファイルから !name! や !res_name! の記述がある部分を捜します。
エディタの検索機能を使えばいいと思います。
!name! 部分が投稿者名が表示される部分なので、この近くのIDを表示したい部分に !id! を記述します。
!res_name! の近くのIDは !res_id! としておきます。

今度はpatio.cgiを開き、こちらも !name! や !res_name! の記述がある部分を捜します。
$tmpl =~ s/!name!/$nam/g;
のように !name! を$namなどで変換する部分があると思います。$namが投稿者名ですが、
この行より前に、ログファイルから$namを取り出す処理をしている部分があるはずで、それを捜します。
今度は $nam で上方向に検索するとすぐ見つかると思います。

my ($no2,$sub,$nam,$eml,$com,$date,$ho,$pw,$url,$mlo,$myid,$tim,$up1,$up2,$up3) = split(/<>/, $par);

というような部分です。IDはこのログファイルの最後に保存されているので、

my ($no2,$sub,$nam,$eml,$com,$date,$ho,$pw,$url,$mlo,$myid,$tim,$up1,$up2,$up3,$id) = split(/<>/, $par);

と変更して$idにIDを保存します。

そして先ほどの

$tmpl =~ s/!name!/$nam/g;
の下にIDを置き換える処理
$tmpl =~ s/!id!/$id/g;

を追加します。

!res_name! についても同様に
$tmp =~ s/!res_name!/$nam/g;
のような場所を捜し、その少し前のログからのデータ抽出処理

my ($no,$sub,$nam,$eml,$com,$date,$ho,$pw,$url,$mlo,$myid,$tim,$up1,$up2,$up3) = split(/<>/);

のような部分を

my ($no,$sub,$nam,$eml,$com,$date,$ho,$pw,$url,$mlo,$myid,$tim,$up1,$up2,$up3,$res_id) = split(/<>/);

と書き換え、

$tmp =~ s/!res_name!/$nam/g;
の下に
$tmp =~ s/!res_id!/$res_id/g;

を追加する。
といった感じです。
どの関数内の処理を書き換えるべきかは、検証していませんので、そのあたりはご自分で試行錯誤してください。


記事No: 15000
投稿日: 2016/07/10(Sun) 18:31:35
タイトルRe^6: WebPatio5.11にID自動生成機能を
ID情報: hirayama
投稿者: hirayama
URLhttp://shade-search.com/sts/fsw/wiki.cgi

すみません。私もすでにわけわからなくなっているようで、
クッキーについてかなりいい加減なことを書いていました。
patio.cgiにあるクッキー関数の流用ではうまくいかないというか、かなり面倒なことをしなければいけないので、
別にID専用のクッキー関数を作ったほうが混乱せずに済みそうです。
そしてクッキー保存はpatio.cgi、regist.cgiそれぞれで行う必要があるので、
regist.cgi ではなく、init.cgiに追加してしまうのが良さそうです。名前も変えます。

sub set_idcookie {
my @data = @_;

my ($sec,$min,$hour,$mday,$mon,$year,$wday,undef,undef) = gmtime(time + 60*24*60*60);
my @mon = qw|Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec|;
my @week = qw|Sun Mon Tue Wed Thu Fri Sat|;

# 時刻フォーマット
my $gmt = sprintf("%s, %02d-%s-%04d %02d:%02d:%02d GMT",
$week[$wday],$mday,$mon[$mon],$year+1900,$hour,$min,$sec);

# URLエンコード
my $cook;
foreach (@data) {
s/(\W)/sprintf("%%%02X", unpack("C", $1))/eg;
$cook .= "$_<>";
}

print "Set-Cookie: FORID=$cook; expires=$gmt\n";
}

sub get_idcookie {
# クッキー取得
my $cook = $ENV{HTTP_COOKIE};

# 該当IDを取り出す
my %cook;
foreach ( split(/;/, $cook) ) {
my ($key,$val) = split(/=/);
$key =~ s/\s//g;
$cook{$key} = $val;
}

# URLデコード
my @cook;
foreach ( split(/<>/, $cook{'FORID'}) ) {
s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("H2", $1)/eg;
s/[&"'<>]//g;

push(@cook,$_);
}
return @cook;
}

この2個をinit.cgiに追加します。
これに合わせてsub create_id2も以下のように変わります。

sub create_id2 {
my ($test,$salt) = &get_idcookie;
if (!$salt) {
my $length = 8;
my @seed = ('a'..'z', 'A'..'Z', 0..9);
$salt = '';
while(length($salt) < $length) {
$salt .= @seed[int rand(scalar @seed)];
}
&set_idcookie($test,$salt);
}
use Digest::MD5 qw/md5_hex/;

# MD5で生成した文字列が長いので、先頭から10文字だけ取り出す
my $id = substr(md5_hex($salt),0,10);
return $id;
}


記事No: 15001
投稿日: 2016/07/13(Wed) 05:59:33
タイトルRe^7: WebPatio5.11にID自動生成機能を
ID情報: rick7634
投稿者: RICK

長々と詳しい説明ありがとうございました。
ただ、ちょっと難しそうに感じたので今回は見送ろうと思います。
本当に有難うございました。


[検索ページ] [掲示板]