这段代码充满了安全漏洞和逻辑错误,但我已经尽力重写它。
$user = 'root';
$host = 'localhost';
$password = '';
$database = 'online_examination';
// Attempt to connect to MySQL
if( !( $connection = mysql_connect( $host , $user , $password ) ) ){
die( 'Failed to connect to server' );
}elseif( !( $db = mysql_select_db( $database , $connection ) ) ){
die( 'Failed to connect to database' );
}
// Default values for Form Submitted Fields
$fn = $ln = $un = $pass = false;
// Check if Form Submitted
if( $_POST ){
// For each value, perform some basic validation before trusting them
if( isset( $_POST['fn'] ) && $_POST['fn']!='' )
$fn = $_POST['fn'] ; // firstname
if( isset( $_POST['ln'] ) && $_POST['ln']!='' )
$ln = $_POST['ln'] ; // lastname
if( isset( $_POST['un'] ) && $_POST['un']!='' )
$un = $_POST['un'] ; // username
if( isset( $_POST['pw'] ) && $_POST['pw']!='' )
$pass = $_POST['pw'] ; // password
}
// If a Username was submitted
if( !$fn || !$ln || !$un || !$pw ){
// One or more of the fields were empty or not submitted.
// Show the form again (maybe with an error message)
}else{
// Perform a Query looking for any instances where the same username is already in use
$query = 'SELECT COUNT(*) AS matches FROM user_info WHERE username="'.mysql_real_escape_string( $un ).'"';
$result = @mysql_query( $query , $connection ) ;
if( !$result ){
die( 'Query for Usernames Failed' );
}
$row = mysql_fetch_array( $result )
if( $row['matches']!=0 ){
// The Username is already in use
if( !headers_sent() ){
header( 'Location: /username_exists.php' );
}else{
echo 'Username already in use - <a href="/username_exists.php">Click here</a>';
}
die();
}
// If we have gotten to this point, the username is OK to use
$sqlTpl = 'INSERT INTO user_info ( firstname , lastname , username , password ) VALUES ( "%s" , "%s" , "%s" , "%s" )';
$sqlStr = sprintf( $sqlTpl ,
mysql_real_escape_string( $fn ) ,
mysql_real_escape_string( $ln ) ,
mysql_real_escape_string( $un ) ,
mysql_real_escape_string( $pw ) );
$result = mysql_query( $sqlStr , $connection );
if( $result ){
if( !headers_sent() ){
header( 'Location: /successfully_registered.php' );
}else{
echo 'Successfully registered - <a href="/successfully_registered.php">Click here</a>';
}
die();
}else{
// Something went wrong
}
}
臀部的几点:
- 遍历所有返回的行并单独匹配它们是检查值是否存在的一种钝方法。SQL 在做这种事情方面要好得多 - 阅读它。
- 执行检查以查看密码是否已被使用是没有意义的。我敢打赌,StackOverflow 上的一两个人拥有相同的密码,但他们没有收到提示“有人已经将 'abc123' 作为密码。选择另一个”的消息。如果有的话,这种消息是一种安全风险,而不是一种安全措施。
- 永远不要相信输入。假设会有一个 POST 提交是灾难的根源。
- 因此,不验证您获得的任何输入。
- 更重要的是不要将其转义以在数据库查询中使用。谷歌搜索“小鲍比桌”。
- 如果您要存储密码,则切勿以纯文本形式存储它们。它们应该被散列和加盐。(同样,谷歌是你的朋友。)
- 假设您可以更改标题是需要谨慎的事情。检查
headers_sent()
是一个很好的做法。
- 随时测试错误。一开始的一个小错误,可以被检测到并中止任何后续操作,总比让一个小错误滚雪球要好。
查看一些预先存在的教程和/或处理用户注册的 PHP 类。他们中的很多人都有好主意,您应该将其纳入您的解决方案,而不是重新发明轮子。