这是我的代码:
function register($user, $pass) {
//check if username exists
$login = query("SELECT username FROM login WHERE username='%s' limit 1", $user);
if (count($login['result'])>0) {
errorJson('Username already exists');
}
//try to register the user
$result = query("INSERT INTO login (username, pass) VALUES('%s','%s')", $user, $pass);
if (! $result['error']) {
//success
login($user, $pass);
} else {
//error
//errorJson('Registration failed');
errorJson($result['error']);
}
}
function login($user, $pass) {
$result = query("SELECT IdUser, username FROM login WHERE username='%s' AND pass='%s' limit 1", $user, $pass);
if (count($result['result'])>0) {
//authorized
$_SESSION['IdUser'] = $result['result'][0]['IdUser'];
print json_encode($result);
} else {
//not authorized
errorJson('Authorization failed');
}
}
我使用用户名和密码调用register,并且DB中的两个字段都是空的。插入通常是因为自动递增的主键正在增加 - 只是字段为空。
这就是我创建用户名的方式。
CREATE TABLE `login` (
`IdUser` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(45) NOT NULL,
`pass` varchar(45) NOT NULL,
PRIMARY KEY (`IdUser`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
这是我的查询功能:
//executes a given sql query with the params and returns an array as result
function query() {
global $link;
$debug = false;
//get the sql query
$args = func_get_args();
$sql = array_shift($args);
//secure the input
for ($i=0;$i<count($args);$i++) {
$args[$i] = urldecode($args[$i]);
$args[$i] = mysql_real_escape_string($link, $args[$i]);
}
//build the final query
$sql = vsprintf($sql, $args);
if ($debug) print $sql;
//execute and fetch the results
$result = mysql_query($sql, $link);
if (mysql_errno($link)==0 && $result) {
$rows = array();
if ($result!==true)
while ($d = mysql_fetch_assoc($result)) {
array_push($rows,$d);
}
//return json
return array('result'=>$rows);
} else {
//error
return array('error'=>'Database error');
}
}
我已经批准$ user和$ pass在执行INSERT INTO之前包含正确的值。
答案 0 :(得分:1)
您没有在数据库中获得结果,因为您在不调用sprintf的情况下使用sprintf语法。尝试:
$sql=sprintf("INSERT INTO login (username, pass) VALUES('%s','%s')", $user, $pass);
$result = query($sql);
编辑:进一步检查时,您的查询功能似乎正在做一些不寻常的事情。我猜你的$ args数组没有你期望的值。在$ args上做一个print_r,看看它是不是和你期望的一样。
答案 1 :(得分:0)
在查询中使用它们之前,应该在变量上使用某种转义以避免注入攻击。此外,你真的不应该使用纯文本密码,它确实是非常糟糕的安全方法,即使使用md5或sha,也不再被认为是安全的(虽然比纯文本更好,但由于许多词典只有非常强的密码)。
`pass` varchar(45) NOT NULL,
自PHP 5.5.0起,不推荐使用扩展$query
,$mysql_real_escape_string
(等),您应该使用mysqli或PDO。
使用mysqli(或PDO)也有助于解决您在函数中遇到的问题,因为它们提供了PHP库中已有的方法来将查询封装在类中。此外,在您使用准备好的陈述的同时,您将解决您的安全问题。
我知道这并没有直接回答你的问题(我可能会因此而被投票)我觉得交换到mysqli或PDO会解决你的问题,因为这是一个更好的方法,它更安全,一旦你知道它使用起来同样容易,而且它们都是在库中构建的,因此未来的PHP更新中将包含安全更新和新功能等。
PDO vs mysqli是基于要求(等)的选择,但是我使用mysqli并且在学习曲线时,最终发现它很容易。我将它与crypt / blowfish一起使用,并使用salt在数据库中保存密码。每个密码都应该有自己独特的随机盐,并使用加密密码保存在数据库中(不需要隐藏盐)。
它被Wordpress,Drupal和大多数其他专业软件和网络公司使用,因为它是最强大,最安全的密码管理系统。
Blowfish消除了制作盐和散列的痛苦,因为所有这些都是一次性返回密码创建的。它创建加密密码salt,并返回您刚存储在DB中的整个字符串。 然后使用已经提供的功能,您可以检查登录密码等。
有关为何从MD5等进行更改的信息: http://php.net/manual/en/faq.passwords.php
这很简单,例如:
require('PasswordHash.php');//you download this file, and just include it
//it contains all the hashing engine etc
// $PostPassword is the one they entered in a form (etc)
$CreateHash = new PasswordHash(8, FALSE);
$HashPassword = $CreateHash->HashPassword($PostPassword);
// $HashPassword is the hashed and salted password you store in the db
// (should always be 60 chars, check with strlen)
// Don't use your own salt, it's not worth it
// and you end up having to use it/store it/remember it
// when checking their password for login etc.
// just use the built in blowfish random salting algos
// Then to check their pass (ie login)
// Query and select their password from DB ($DbPass)
// with their username entered in the login form
// Check it against the password they entered in form
// (once hashed again of course to match the salted/hashed DB one)
$CreateHash = new PasswordHash(8, FALSE);
$CheckPass = $CreateHash->CheckPassword($PostPassword, $DbPass);
if ($CheckPass)
{
// password matches
}
else
{
//not match, tell them to try again etc
}
// you can use various checks on this, mainly check if the
// library exists (to avoid php errors etc)
if(defined("CRYPT_BLOWFISH") && CRYPT_BLOWFISH)
{
// do all your password stuff
}
非常简单!