0

这是我的代码:

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');
    }
}

我用用户名和密码调用注册,数据库中的两个字段都是空的。插入正常进行,因为自动递增的主键正在增加 - 只是字段为空。

这就是我创建用户名的方式。

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');
    }
}

在执行 INSERT INTO 之前,我检查了 $user 和 $pass 是否包含正确的值。

4

2 回答 2

1

您没有在数据库中获得结果,因为您使用的是 sprintf 语法而不调用 sprintf。尝试:

$sql=sprintf("INSERT INTO login (username, pass) VALUES('%s','%s')", $user, $pass);

$result = query($sql);

编辑:进一步检查,您的查询功能似乎在做一些不寻常的事情。我猜你的 $args 数组没有你期望的值。在 $args 上执行 print_r 并查看它是否与您期望的不同。

于 2013-08-17T10:55:34.393 回答
0

在查询中使用它们之前,您应该在变量上使用某种转义以避免注入攻击。此外,您真的不应该使用纯文本密码,这确实是非常糟糕的安全方法,即使使用 md5 或 sha,也不再被认为是安全的(虽然比纯文本更好,但由于许多字典只有非常强的密码)。

  `pass` varchar(45) NOT NULL,

从 PHP 5.5.0 开始不推荐使用extensions $query, $mysql_real_escape_string(etc),您应该使用 mysqli 或 PDO。使用 mysqli(或 PDO)也将有助于解决您在函数中遇到的问题,因为它们提供了 PHP 库中已有的方法来将您的查询封装在类中。此外,伴随您使用准备好的语句,您将解决您的安全问题。

我知道这并不能直接回答您的问题(因此我可能会被否决)同样易于使用,而且它们内置在库中,因此安全更新和新功能等将包含在未来的 PHP 更新中。

PDO 与 mysqli 是基于需求(等)的选择,但我使用 mysqli,虽然学习曲线很复杂,但最终发现它很容易。我将它与 crypt/blowfish 一起使用,并用盐将密码保存在数据库中。每个密码都应该有自己唯一的随机盐,并使用加密密码保存在数据库中(无需隐藏盐)。

它被 Wordpress、Drupal 和大多数其他专业软件和网络公司使用,因为它是最强大和最安全的密码管理系统。

Blowfish 消除了制作盐和散列的痛苦,因为所有这些都是在返回的密码中一次性创建的。它创建加密密码、salt 并返回您刚刚存储在数据库中的整个字符串。然后使用已经提供的功能,您可以检查登录密码等。

关于为什么从 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
  }

很简单!

于 2013-08-17T11:02:22.610 回答