我正在创建一个简单的perl脚本来创建一个注册用户的网页。这对我来说只是一个学习计划。这很简单。我将在浏览器上显示一个页面。用户输入名称,用户名和密码。用户按下提交后,我将根据数据库检查用户名。如果数据库中存在用户名,我只想显示错误并再次显示注册页面。我正在使用cgi->重定向功能。我不确定这是否应该如何使用重定向功能。它不像我想的那样工作。它显示“文件已移至此处”。请指出正确的方法。谢谢。
这是脚本
registeruser.pl
#!/usr/bin/perl
print "Content-type: text/html\n\n";
print <<PAGE;
<html>
<head>
<link rel="stylesheet" type="text/css" href="tracker.css"/>
</head>
<body>
<div id="header">
<h1> Register New User</h1>
</div>
<div id="content">
<form action="adduser.pl" method="POST">
<b>Name:</b> <input type="text" name="name"><br>
<b>UserName:</b> <input type="text" name="username"><br>
<b>Password:</b> <input type="password" name="password"><br>
<input type="submit">
</div>
</body>
<html>
PAGE
adduser.pl
#!/usr/bin/perl
use CGI;
use DBI;
$cgiObj = CGI->new;
print $cgiObj->header ('text/html');
# get post data
$newUser = $cgiObj->param('username');
$newName = $cgiObj->param('name');
$newPass = $cgiObj->param('password');
# set up sql connection
$param = 'DBI:mysql:Tracker:localhost';
$user = 'madison';
$pass = 'qwerty';
$connect = DBI->connect ($param, $user, $pass);
$sql = 'select user from users where user = "' . $newUser . '"';
$query = $connect->prepare ($sql);
$query->execute;
$found = 0;
while (@row = $query->fetchrow_array)
{
$found = 1;
}
if ($found == 0)
{
# no user found add new user
$sql = 'insert into users (user, name, passwd) values (?, ?, ?)';
$insert = $connect->prepare ($sql);
$insert->execute ($newUser, $newName, $newPass);
}
else
{
# user already exists, get new user name
# What do I do here ????
print $cgiObj->redirect ("registerusr.pl");
}
答案 0 :(得分:2)
要注意的一件事,SQL Injection。对于图示的示例,Little Bobby Tables。
现在你的代码是不可靠的,并且可以让人们对你的数据库做坏事。 DBI提供占位符作为使用用户输入查询数据库的安全方式。示例http://bobby-tables.com/perl.html
此外,在这个时代,即使CGI模块警告您不要使用它:
这个决定的理由是CGI.pm不再被认为是开发Web应用程序的良好实践,包括快速原型设计和小型Web脚本。目前,有更好,更清洁,更快速,更容易,更安全,更具可扩展性,更具可扩展性,更现代化的替代品。这些将记录在CGI::Alternatives。
我建议您使用Dancer让您的生活更轻松。
答案 1 :(得分:1)
三件事
在每个perl脚本中包含use strict;
和use warnings;
。没有例外。
这是成为更好的perl程序员的第一件事。它将在开发和测试期间为您节省不可估量的时间。
不要使用重定向在表单处理和表单显示之间切换
将表单显示和表单处理保存在同一脚本中。这使您可以在表单中显示错误消息,并仅在成功处理的表单上转到新步骤。
您只需要测试request_method
以确定是否需要处理表单或仅显示该表单。
CGI
适用于学习perl,但请查看CGI::Alternatives
了解实时代码。
以下是您在考虑前2条准则时重构的表单:
register.pl:
#!/usr/bin/perl
use strict;
use warnings;
use CGI;
my $q = CGI->new;
my $name = $q->param('name') // '';
my $username = $q->param('username') // '';
my $password = $q->param('password') // '';
# Process Form
my @errors;
if ( $q->request_method() eq 'POST' ) {
if ( $username =~ /^\s*$/ ) {
push @errors, "No username specified.";
}
if ( $password =~ /^\s*$/ ) {
push @errors, "No password specified.";
}
# Successful Processing
if ( !@errors ) {
# Obfuscate for display
$password =~ s/./*/g;
print $q->header();
print <<"END_PAGE";
<html>
<head><title>Success</title></head>
<body>
<p>Name = $name</p>
<p>Username = $username</p>
<p>Password = $password</p>
</body>
</html>
END_PAGE
exit;
}
}
# Display Form
print $q->header();
print <<"END_PAGE";
<html>
<head>
<link rel="stylesheet" type="text/css" href="tracker.css"/>
</head>
<body>
<div id="header">
<h1>Register New User</h1>
</div>
@{[ @errors ? join("\n", map "<p>Error: $_</p>", @errors) : '' ]}
<div id="content">
<form action="register.pl" method="POST">
<b>Name:</b> @{[ $q->textfield( -name => 'name' ) ]}<br>
<b>UserName:</b> @{[ $q->textfield( -name => 'username' ) ]}<br>
<b>Password:</b> @{[ $q->password_field( -name => 'password' ) ]}<br>
<input type="submit">
</div>
</body>
<html>
END_PAGE
__DATA__