Perlで、パスワードをハッシュ化してユーザー情報を管理する

Perlで、パスワードをハッシュ化してDBに格納、ユーザー情報を管理するプログラムです。ユーザー登録と、ログイン機能があります。DBはMySQLを使用しました。学習用にシンプルに作りました。動作はしますが、内容についてご指摘いただけると幸いです。

  • きっかけ

http://neta.ywcafe.net/000910.htmlを見て作ってみようと思いました。

  • 参照

Perl を使って DES/MD5 についてを参考に作ってみました。

  • DB定義
CREATE TABLE `user` (`user_name` varchar(128) default NULL,`password` varchar(128) default NULL) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  • signup.html ~ユーザー登録画面
<html>
    <head>
    <title>ユーザー登録フォーム</title>
    </head>
<body>

<form name="form" action="./signup.pl" method="post">
    user_name:<input type="text" name="user_name">
    password:<input type="password" name="password">
    <input type="submit" name="submit" value="登録">
</form>

</body>
</html>
  • signup.pl ~ユーザー登録プログラム
#!/usr/bin/perl

use strict;
use warnings;
use CGI;
use DBI;

#user_testデータベース名/ユーザー/パスワード
my $db_name='user_test';
my $db_user='user_db';
my $db_passwd='user_pass';
my $db_host='127.0.0.1';

#フォームからのパラメタ取得
my $q = new CGI;
my $user_name = $q->param('user_name');
my $password = $q->param('password');
my $url='./signup.pl';

#ヘッダ
print "Content-type: text/html\n\n";
print <<HEAD;
<html>
  <head>
	<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
	<title></title>
  </head>
  <body>
HEAD

#DB接続
    my $db = DBI->connect("dbi:mysql:dbname=$db_name","$db_user","$db_passwd",{RaiseError=>0,AutoCommit=>1}) || &print_error(" データベースへの接続に失敗しました。<br>\n");
#SQL文作成
    my $sql="SELECT user_name FROM user WHERE user_name = '$user_name'";
#SQL設定
    my $st = $db->prepare($sql);
#SQL実行
    my $res = $st->execute;

my $exist=$st->fetchrow_array();
$st->finish;

#ユーザー名の登録チェック
if($exist eq "")
{
    my $md5_password = &md5hash($password);
    my $sth = $db->prepare("INSERT INTO user VALUES ('$user_name', '$md5_password')");
    $sth->execute;
    $sth->finish;
    print "ユーザー名$user_nameを登録しました";
}else{
    print "ユーザー名は登録されています";
}

print <<FOOT;
</body>
</html>
FOOT

#DB切断
    $db->disconnect;

sub md5hash()
{
    my $pass_org = shift;
    srand();
    my @salts = ( "A".."Z", "a".."z", "0".."9", ".", "/" );
    my $salt = $salts[int(rand(64))] . $salts[int(rand(64))];
    return crypt($pass_org, '$1$' . $salt);
}

※ユーザー登録時に入力文字数チェックをしていません

  • signin.html ~ログイン画面
<html>
    <head>
    <title>ユーザー登録フォーム</title>
    </head>
<body>

<form name="form" action="./signin.pl" method="post">
    user_name:<input type="text" name="user_name">
    password:<input type="password" name="password">
    <input type="submit" name="submit" value="登録">
</form>

</body>
</html>
  • signin.pl ~ログインプログラム
#!/usr/bin/perl

use strict;
use warnings;
use CGI;
use DBI;

#user_testデータベース名/ユーザー/パスワード
my $db_name='user_test';
my $db_user='user_db';
my $db_passwd='user_pass';
my $db_host='127.0.0.1';

#フォームからのパラメタ取得
my $q = new CGI;
my $user_name = $q->param('user_name');
my $password = $q->param('password');
my $url='./signin.pl';

#ヘッダ
print "Content-type: text/html\n\n";
print <<HEAD;
<html>
  <head>
	<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
	<title></title>
  </head>
  <body>
HEAD

#DB接続
    my $db = DBI->connect("dbi:mysql:dbname=$db_name","$db_user","$db_passwd",{RaiseError=>0,AutoCommit=>1}) || &print_error(" データベースへの接続に失敗しました。<br>\n");
#SQL文作成
    my $sql="SELECT user_name, password FROM user WHERE user_name = '$user_name'";
#SQL設定
    my $st = $db->prepare($sql);
#SQL実行
    my $res = $st->execute;

    my($db_username, $db_password)=$st->fetchrow_array();
$st->finish;

#ユーザー名とパスワードのチェック
if($db_username eq ""){
    print "ユーザー名またはパスワードが違います";
}elsif($db_password eq crypt($password, $db_password ))
{
    print "ユーザー名$db_usernameでログインしました";
}else{
    print "ユーザー名またはパスワードが違います";
}

print <<FOOT;
</body>
</html>
FOOT

#DB切断
$db->disconnect;

sub md5hash()
{
    my $pass_org = shift;
    srand();
    my @salts = ( "A".."Z", "a".."z", "0".."9", ".", "/" );
    my $salt = $salts[int(rand(64))] . $salts[int(rand(64))];
    return crypt($pass_org, '$1$' . $salt);
}

※ログイン後のセッション管理をしていません
続きPerlで、セッション管理をする(CGI::Session,CGI::Cookie,MySQL使用) - undiscoの日記