如何限制表单的使用或限制访问
Posted
技术标签:
【中文标题】如何限制表单的使用或限制访问【英文标题】:How to limit use on a form or restrict access 【发布时间】:2011-11-03 20:31:03 【问题描述】:我有一个游戏的基本注册表单,基本上它非常新手,它允许用户创建任意数量的帐户。我四处寻找,但找不到任何具体的答案。
我基本上需要一种方法来限制表单的使用或将帐户创建限制为每个 IP 1 个。
这是基本的表单代码:
<?php
/*if($_SERVER['REMOTE_ADDR'] != '::1')
$inRegister = true;
include 'index.php';
die();
*/
if(isset($_GET['username']))
function sendBack($func_value)
$func_data = array('false' => 'REGISTER', 'fail' => 'DATABASE_ERROR', 'true' => 'USERNAME_TAKEN');
include "Pages/$func_data[$func_value].page.php";
include 'checkName.php';
die();
from ;include 'settings.php' ;uses ;
$pMin = PLAYER_MINLEN;
$pMax = PLAYER_MAXLEN;
$pChr = PLAYER_MAXLEN;
$aMin = PASSWORD_MINLEN;
$aMax = PASSWORD_MAXLEN;
$eMin = EMAIL_MINLEN;
$eMax = EMAIL_MAXLEN;
;
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' />
<title>CpBroadcast: Club Penguin Private Server Registration</title>
<link type='text/css' href='CSS/ui-lightness/jquery-ui-1.8.2.custom.css' rel='stylesheet' />
<link type='text/css' href='CSS/register.css' rel='stylesheet' />
<script type='text/javascript' src='JS/MD5.js'></script>
<script type='text/javascript' src='JS/jquery-1.4.2.min.js'></script>
<script type='text/javascript' src='JS/jquery-ui-1.8.2.custom.min.js'></script>
<script type='text/javascript'>
function LTrim(value)
var re = /\s*((\S+\s*)*)/;
return value.replace(re, "$1");
function RTrim(value)
var re = /((\s*\S+)*)\s*/;
return value.replace(re, "$1");
function trim(value)
return LTrim(RTrim(value));
var moderatorTimer = 0;
var isLoggedIn = false;
var suggestValues =
playerName: 'Playername',
passwordA: '',
passwordB: '',
emailAddress: 'EMail@Address.com',
recommended: 'Who told you about this?'
;
var states =
noticePasswords: 0,
noticePlayerName: 0,
noticeEMail: 0
;
function updateStatus(classString, messageString)
$('#statusBar').removeClass('ui-state-error');
$('#statusBar').removeClass('ui-state-highlight');
$('#statusBar').addClass(classString);
var iconString = classString == 'ui-state-error' ? 'ui-icon-alert' : 'ui-icon-info';
$('#statusBar').html('<p><span class="ui-icon ' + iconString + '" style="float: left; margin-right: .3em;"></span>' + messageString + '</p>');
function showLoader(message)
$('#content').html('<div align=\'center\'><img src=\'Images/Loader.gif\' /><br />' + message + '</div>');
function loadContent(url, container)
url = url.split('?');
data = url[1];
url = url[0];
$.ajax(
url: url,
data: data,
success: function(data)
$(container).html(data);
);
function updateNotice(fieldID, fieldData, fieldMessage)
states[fieldID] = Number(fieldData == 'fieldNoticeFail');
fieldID = '#' + fieldID;
$(fieldID).removeClass('fieldNoticeOkay');
$(fieldID).removeClass('fieldNoticeFail');
$(fieldID).addClass(fieldData);
$(fieldID).html(fieldMessage);
$(function()
$('#playerName, #recommended').keyup(function()
var playerName = this.value;
var noticeID = this.id == 'playerName' ? 'noticePlayerName' : 'noticeEMail';
if(playerName.length == 0)
if(this.id == 'recommended') return updateNotice(noticeID, 'fieldNoticeOkay', 'You don\'t have to edit that Field, but it\'s recommended!');
else return updateNotice(noticeID, 'fieldNoticeFail', 'Please enter a Username!');
if(playerName.length < 3) return updateNotice(noticeID, 'fieldNoticeFail', 'The PlayerName is too short! 3 Chars at Minimum!');
if(playerName.length > 12) return updateNotice(noticeID, 'fieldNoticeFail', 'The PlayerName is too long! 12 Chars at Maximum!');
var count = 0;
for(var i = 0; i < playerName.length; ++i) if((chr = playerName.charCodeAt(i)) && (chr > 64 && chr < 91 || chr > 96 && chr < 123)) ++count;
if(!count) return updateNotice(noticeID, 'fieldNoticeFail', 'Woah, you need to at least have one letter in your name.');
return updateNotice(noticeID, 'fieldNoticeOkay', 'Your player name is okay, and very creative! :)');
).trigger('keyup').blur(function()
if(states.noticePlayerName) return;
$.ajax(
url: 'checkName.php',
data: 'username=' + this.value,
success: function(data)
if(data == 'true') return updateNotice('noticePlayerName', 'fieldNoticeFail', 'We are sorry, a member has already taken that name.');
if(data == 'fail') return updateNotice('noticePlayerName', 'fieldNoticeFail', 'Wow, it seems we have lost database connection. Please look at our blog for updates.');
if(data == 'false') return updateNotice('noticePlayerName', 'fieldNoticeOkay', 'I like that playername! Lucky for you, it is available!');
alert(
['Debug TraceBack',
' at CpBroadcast',
' at Register.php',
' at AJAX.success Callback',
' called with Parameter',
' #0: [' + typeof(data) + '] ' + data,
' at checkName.php?username=...',
'',
''].join("\n"));
return updateNotice('noticePlayerName', 'fieldNoticeFail', 'Something is wrong!');
);
);
$('#passwordA, #passwordB').keyup(function()
this.value = trim(this.value);
if(this.value.length == 0)
if(this.id == 'passwordB' && $('#passwordA').val().length != 0) return updateNotice('noticePasswords', 'fieldNoticeFail', 'You have to repeat the Password!');
else return updateNotice('noticePasswords', 'fieldNoticeFail', 'You have to enter a Password!');
if(this.id == 'passwordB' && $('#passwordA').val() != $('#passwordB').val())
return updateNotice('noticePasswords', 'fieldNoticeFail', 'The Passwords don\'t match!');
if(this.value.length < 6) return updateNotice('noticePasswords', 'fieldNoticeFail', 'The Password is too short! 6 Chars at Minimum!');
if(this.value.length > 32) return updateNotice('noticePasswords', 'fieldNoticeFail', 'The Password is too long! 32 Chars at Maximum!');
if($('#passwordB').val().length == 0) return updateNotice('noticePasswords', 'fieldNoticeFail', 'You have to repeat the Password!');
if(this.id == 'passwordA' && $('#passwordA').val() != $('#passwordB').val())
return updateNotice('noticePasswords', 'fieldNoticeFail', 'The Passwords don\'t match!');
return updateNotice('noticePasswords', 'fieldNoticeOkay', 'The Passwords are okay :)');
).trigger('keyup');
$('#emailAddress').keyup(function()
this.value = trim(this.value);
var email = this.value;
if(email.length < 6) return updateNotice('noticeEMail', 'fieldNoticeFail', 'The EMail Address is too short! 6 Chars at Minimum!');
if(email.length > 128) return updateNotice('noticeEMail', 'fieldNoticeFail', 'The EMail Address is too long! 128 Chars at Maximum!');
if(email.split('@').length != 2) return updateNotice('noticeEMail', 'fieldNoticeFail', 'The EMail Address is invalid! It has to contain exactly <b>one</b> @!');
if(email.split('@')[1].split('.').length < 2) return updateNotice('noticeEMail', 'fieldNoticeFail', 'The EMail Address is invalid! The Domain is wrong!');
var emailName = email.split('@')[0];
var emailDomain = email.split('@')[1].split('.');
var emailTLD = emailDomain.pop();
emailDomain = emailDomain.join('.');
if(emailName.length < 1) return updateNotice('noticeEMail', 'fieldNoticeFail', 'You have to specify a Username in the EMail Address!');
if(emailDomain.length < 1) return updateNotice('noticeEMail', 'fieldNoticeFail', 'You have to specify a Domain in the EMail Address!');
if(emailTLD.length < 2) return updateNotice('noticeEMail', 'fieldNoticeFail', 'You have to specify a valid TLD in the EMail Address!');
return updateNotice('noticeEMail', 'fieldNoticeOkay', 'The EMail is okay :)');
).trigger('keyup');
$('document').ready(function()
updateStatus('ui-state-highlight', '<strong>Welcome!</strong> To register for CpBroadcast, click the "Register" button!');
for(var i in suggestValues) $('#' + i).addClass('suggestBox');
$('.suggestBox').focus(function()
if(this.value == suggestValues[this.id]) this.value = '';
this.style.color = '#000000';
);
$('.suggestBox').blur(function()
if(this.value == '') this.value = suggestValues[this.id];
if(this.value == suggestValues[this.id]) this.style.color = '#DADADA';
);
$('.suggestBox').trigger('blur');
);
$('#registerBox').dialog(
modal: true,
autoOpen: false,
width: 320,
beforeclose: function() updateStatus('ui-state-highlight', '<strong>Welcome!</strong> Registration aborted!'); ,
buttons:
'Submit': function()
var sum = 0;
for(var i in states) sum += states[i];
if(sum)
var s = sum == 1 ? '' : 's';
var is = sum == 1 ? 'is' : 'are';
var error = 'There ' + is + ' still ' + sum + ' Mistake' + s + ' in the Regristration Form!';
return (updateStatus('ui-state-error', '<strong>Regristration failed:</strong> ' + error) | alert(error)) && false;
else
$(this).dialog('close');
$(this).dialog('close');
updateStatus('ui-state-highlight', '<strong>Status:</strong> Sending Regristration...');
loadContent('register.php?' +
'username=' + $('#playerName').val() +
'&password=' + $('#passwordA').val() +
'&email=' + $('#emailAddress').val() +
'&color=' + $('#color').val(), '#content');
,
'Cancel': function()
$(this).dialog('close');
);
$('#registerLink').click(function()
$('#registerBox').dialog('open');
return false;
);
$('#registerLink, ul#icons li').hover(
function() $(this).addClass('ui-state-hover'); ,
function() $(this).removeClass('ui-state-hover');
);
);
</script>
</head>
<body>
<div class='ui-widget'><div id='statusBar' class='ui-corner-all'></div></div>
<div align='right'><a href='#' id='registerLink' class='ui-state-default ui-corner-all'><span class='ui-icon ui-icon-newwin'></span>Register</a></div>
<div id='registerBox' title='Register for CpBroadcast'>
<div id='noticePlayerName' class='fieldNotice'></div>
<input type='text' id='playerName' maxlength='<?= $pMax ?>' /><br />
<div id='noticePasswords' class='fieldNotice'></div>
<input type='password' id='passwordA' maxlength='<?= $aMax ?>' /><br />
<input type='password' id='passwordB' maxlength='<?= $aMax ?>' /><br />
<div id='noticeEMail' class='fieldNotice'></div>
<input type='text' id='emailAddress' maxlength='<?= $eMax ?>' /><br />
<input type='text' id='recommended' maxlength='<?= $pMax ?>' /><br />
<div class='fieldNotice'>If you don't pick a Color, we will surprise you by picking one randomly!</div>
<select id='color'>
<option value='0'>Pick a Color</option>
<option value='1'>Blue</option>
<option value='2'>Green</option>
<option value='3'>Pink</option>
<option value='4'>Black</option>
<option value='5'>Red</option>
<option value='6'>Orange</option>
<option value='7'>Yellow</option>
<option value='8'>Dark Purple</option>
<option value='9'>Brown</option>
<option value='10'>Peach</option>
<option value='11'>Dark Green</option>
<option value='12'>Light Blue</option>
<option value='13'>Lime Green</option>
<option value='15'>Aqua</option>
</select>
</div>
<div id='content' class='ui-corner-all'>
<?php
?>
Welcome to CpBroadcast, an amazing and powerful Club Penguin Private Server! We're glad you decided to register for our server, and we hope you have a good stay here.<br>
<a href="http://www.cpbroadcast.com/h4-club-penguin-private-server-2011">Click here to play!</a><br>
<a href="http://www.cpbroadcast.com/t3480-how-to-register">How to register</a>
<center><script type="text/javascript"><!--
google_ad_client = "ca-pub-5148796547228631";
/* CPB 1 */
google_ad_slot = "9834355448";
google_ad_width = 250;
google_ad_height = 250;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></center>
</div>
</body>
</html>
注册成功后,发送到这个表单:
<?php
function updateStatus($func_classString, $func_messageString)
?><script type="text/javascript">
updateStatus("<?= $func_classString ?>", "<?= $func_messageString ?>");
</script><?php
$password = $_GET['password'];
$username = trim($_GET['username']);
$email = trim($_GET['email']);
$color = (integer) $_GET['color'];
if($color < 1 || $color > 15) $color = rand(1, 15);
if(strlen($username) < PLAYER_MINLEN) die('Username Too Short');
$uppername = strtoupper($username);
if(str_replace(str_split('ABCDEFGHIJKLMNOPQRSTUVWXYZ'), '', $uppername) == $uppername) die('Username Error');
//if(!Utils::CheckString('0123456789ABCDEF', 32, 32, $password)) die('Password Error');
if(!Utils::CheckString(PLAYER_CHARS,PLAYER_MINLEN,PLAYER_MAXLEN, $username)) die('Username Error');
if(!Utils::CheckString(EMAIL_CHARS,EMAIL_MINLEN,EMAIL_MAXLEN, $email)) die('Email Error');
$query = sprintf("SELECT * FROM `accs` WHERE `name` = '%s'",
mysql_real_escape_string($username));
$checkuser = mysql_query($query);
$username_exist = mysql_num_rows($checkuser);
if($username_exist > 0)
die("Name Taken!");
$player = array(
'email' => $email,
'registerIP' => $_SERVER['REMOTE_ADDR'],
'registertime' => time(),
'color' => $color,
'head' => 0,
'face' => 0,
'neck' => 0,
'body' => 0,
'hands' => 0,
'feet' => 0,
'pin' => 413,
'photo' => 0,
'items' => array(1, 444),
'coins' => 50000,
'isModerator' => false,
'isBanned_' => false,
'buddies' => array(),
'ignore' => array(),
'stamps' => array(),
'stampColor' => 1,
'stampHighlight' => 1,
'stampPattern' => -1,
'stampIcon' => 1,
'stampIcon' => 1,
'igloo' => 1,
'music' => 0,
'floor' => 0,
'furniture' => array(),
'roomFurniture' => "",
'mood' => "I am new to CpBroadcast",
);
$query = sprintf("INSERT INTO `accs` (`ID`,`name`,`crumbs`,`password`)
VALUES ('NULL', '%s', '%s', '%s');",
mysql_real_escape_string($username),
mysql_real_escape_string(serialize($player)),
mysql_real_escape_string(md5($password)));
mysql_query($query) or die("Player DB Error: " .mysql_error());
// Get Last ID
$playerID = mysql_insert_id(); ?>
<p><strong>You've been registered succesfully</strong><br />
Thank you for signing up at CpBroadcast!<br /></p>
<a href="http://www.cpbroadcast.com/h4-club-penguin-private-server-2011">Click here to play!</a>
<br />
<a href="http://www.cpbroadcast.com/t3480-how-to-register">How to register</a> <br />
<p><small>In case you were wondering, your PlayerID is <strong><?= $playerID ?></strong></small> :)</p>
<?php updateStatus('ui-state-highlight', '<strong>CpBroadcast Registration Done:</strong> Successful!'); ?>
结果如下:http://cpcsy.co.cc/register/
如果用户尝试使用已获取的用户名或电子邮件,则该表单基本上会做出响应。我希望这也适用于 IP 地址。
我可以添加任何东西来增加安全性并减少垃圾邮件帐户。
【问题讨论】:
如果那是“基本的”,我不想看到“复杂”的表格是什么样子的。 【参考方案1】:限制每个 IP 1 不是要走的路。由于代理服务器,有很多用户使用完全相同的 IP 地址。这只会惹恼你的真实用户。此外,大多数互联网用户都是 DHCP 的,这意味着他们的 IP 地址会定期更改。如果您通过 IP 阻止,它充其量只是暂时的,这意味着下一个获得该地址的人将无法玩游戏。您可能不会看到很多碰撞,但这是有可能的。
解决这个问题的常见方法有以下三种:
-
在“激活”帐户之前,请向他们发送电子邮件。在您的代码中验证电子邮件地址不能重复。
添加一个简单的验证码。这将消除很多机器人。
完全忽略这个问题。
这里的第三个选项不是开玩笑,而是真正的回应。很多人喜欢在给定的游戏中运行多个帐户。这通常是一种战术性的事情,可能会导致该人的粘性增加。意思是,他们会继续回来。
这真的归结为您开发这款游戏的原因。你希望从中赚钱吗?如果是这样,怎么做?如果是通过付费订阅,那么一个人拥有的账户越多,你从他们身上赚到的钱就越多。应用内购买也是如此。如果是通过广告,那么他们在游戏中的参与度越高(无论选择的帐户如何),您就越有机会从他们身上获得收益。
简而言之,看看几件事。一个人在创建多个帐户时会获得什么优势?第二,这个优势真的不能接受吗?如果不是,则忽略它。如果是,则确定如何通过消除该优势来重新平衡游戏,问题就会消失。
【讨论】:
好吧,我想限制的唯一原因是被禁止的用户创建新帐户和随机用户创建垃圾邮件帐户。电子邮件激活似乎是最好的方法,有没有在线文章可以告诉我如何在上面的编码中实现它。 没有必要的文章... 在他们填写了创建帐户屏幕后,将信息发布到保留表并发送一封电子邮件,其中包含包含一些随机 ID 的激活链接。当他们单击链接时,将帐户从保留表移动到您的主帐户表。就像注册 Facebook 或几乎任何其他在线服务一样。 这听起来非常简单,不过我不太确定该怎么做。 @Nick:作为另一个问题提出;我相信你会在大约 5 分钟内获得完整的代码……或者至少是一篇定义非常明确的“文章”。 ;)【参考方案2】:不要使用用户 IP。这意味着我和我的室友无法注册,因为我们拥有相同的 IP。
最好的方法是在注册时要求提供电子邮件地址。当有人注册时,发送一封带有激活链接的电子邮件,并让他们的帐户处于非活动状态,直到他们点击它。他们仍然可以创建多封电子邮件来解决这个问题,但大多数人都很懒惰,不会这样做。
【讨论】:
【参考方案3】:在不阅读所有代码的情况下,我会选择交易计数WHERE registerIP = $_SERVER['REMOTE_ADDR']
,如果您得到的不是 0,则表明该 IP 上的某个人已经注册了。
另外,请查看 MySQL 的 INET_ATON() 函数以存储这些 IP
执行此操作的快速代码:
在插入查询之前,添加如下内容:
$result = mysql_query("SELECT COUNT(*) FROM accs WHERE registerIP = '$_SERVER['REMOTE_ADDR']'");
$count = mysql_fetch_row($result);
if (!empty($count[0])) die('Your IP has already been used');
但正如其他人所说,使用不同的帐户限制机制可能会获得更好的结果。
【讨论】:
以上是关于如何限制表单的使用或限制访问的主要内容,如果未能解决你的问题,请参考以下文章