Php 阻止用户生成身份验证令牌

Php 阻止用户生成身份验证令牌,php,ios,api,security,Php,Ios,Api,Security,因此,我有一个API,其端点类似于SoPOSThttp://localhost:8080/api/authenticate。 去那里,你会发一封电子邮件和密码,你会得到一个身份验证令牌。到目前为止似乎还很稳定 现在注册怎么样。我需要创建某种请求令牌,但是如何防止随机用户通过API创建请求令牌呢?我正在考虑从http://localhost:8080/api/request然后在用户注册时返回并检查它是否存在。问题是任何人都可以进入http://localhost:8080/api/request

因此,我有一个API,其端点类似于So
POSThttp://localhost:8080/api/authenticate
。 去那里,你会发一封
电子邮件
密码
,你会得到一个身份验证令牌。到目前为止似乎还很稳定


现在注册怎么样。我需要创建某种请求令牌,但是如何防止随机用户通过API创建请求令牌呢?我正在考虑从
http://localhost:8080/api/request
然后在用户注册时返回并检查它是否存在。问题是任何人都可以进入
http://localhost:8080/api/request
,即使他们不打算注册。有什么想法吗?

在生成身份验证令牌(cookie)之前对用户进行身份验证。。。因此,编写一个查询,从电子邮件/密码匹配的用户表中提取id。。。因此,只有当查询返回一个id时,您才知道用户存在并且已“验证”,因此您现在可以生成一个身份验证令牌(cookie),将其设置为usrid

但是,将cookie设置为usrid不是一个好的实践!由于客户端的任何人都可以在POST请求中轻松设置/传递带有数字的cookie。。。您需要实现某种加密机制来生成一个“会话”,然后将其用作唯一的防黑客用户标识符

我在下面的代码中编写了一个简单的加密函数,您可以使用它

<?php
//CHECK IF POST DATA IS EMPTY IF SO KILL THE SCRIPT
if(empty($_POST['email']) || empty($_POST['pass'])){
    //echo("error msg"); 
    die();
}
$mysqli = new mysqli('localhost', 'root', 'root', 'accounts');
$pass = md5($_POST['pass']);

$query = "SELECT `id` FROM `users` WHERE `email` = '" 
    . $mysqli->real_escape_string($_POST['email']) 
    . "' AND `password` = '" 
    . $mysqli->real_escape_string($_POST['pass']) . "'"; 

//INITIATE DB REQUEST
$result = $mysqli->query($query);
//SELECT ID(OBJ) FROM THE RESULT OBJECT
$usrid = $result->fetch_object()->id;
//IF $USRID IS TRUE... USER DOES EXIST (AUTHENTICATED) 
if ($usrid) {
    $sesh = create_session($usrid);
    update_session($usrid, $sesh);
    setcookie("usersesh", $sesh, 0,"/");
} else {
    //echo("error msg");
}

$result->free();
$mysqli->close();
function create_session($usrid) {
    $time = microtime();
    $hash = substr($time, 2, 3);
    $key = $usrid * $hash;
    $sesh = md5($key);
    return $sesh;   
}
function update_session($usrid, $sesh) {
    $mysqli = new mysqli('localhost', 'root', 'root', 'accounts');
    $query = "UPDATE `users` SET `session` = '" 
        . $mysqli->real_escape_string($sesh) . "' WHERE `id` = '" 
        . $mysqli->real_escape_string($usrid) . "'"; 
    $mysqli->query($query);
    $mysqli->close();   
}
?>

在生成身份验证令牌(cookie)之前对用户进行身份验证。。。因此,编写一个查询,从电子邮件/密码匹配的用户表中提取id。。。因此,只有当查询返回一个id时,您才知道用户存在并且已“验证”,因此您现在可以生成一个身份验证令牌(cookie),将其设置为usrid

但是,将cookie设置为usrid不是一个好的实践!由于客户端的任何人都可以在POST请求中轻松设置/传递带有数字的cookie。。。您需要实现某种加密机制来生成一个“会话”,然后将其用作唯一的防黑客用户标识符

我在下面的代码中编写了一个简单的加密函数,您可以使用它

<?php
//CHECK IF POST DATA IS EMPTY IF SO KILL THE SCRIPT
if(empty($_POST['email']) || empty($_POST['pass'])){
    //echo("error msg"); 
    die();
}
$mysqli = new mysqli('localhost', 'root', 'root', 'accounts');
$pass = md5($_POST['pass']);

$query = "SELECT `id` FROM `users` WHERE `email` = '" 
    . $mysqli->real_escape_string($_POST['email']) 
    . "' AND `password` = '" 
    . $mysqli->real_escape_string($_POST['pass']) . "'"; 

//INITIATE DB REQUEST
$result = $mysqli->query($query);
//SELECT ID(OBJ) FROM THE RESULT OBJECT
$usrid = $result->fetch_object()->id;
//IF $USRID IS TRUE... USER DOES EXIST (AUTHENTICATED) 
if ($usrid) {
    $sesh = create_session($usrid);
    update_session($usrid, $sesh);
    setcookie("usersesh", $sesh, 0,"/");
} else {
    //echo("error msg");
}

$result->free();
$mysqli->close();
function create_session($usrid) {
    $time = microtime();
    $hash = substr($time, 2, 3);
    $key = $usrid * $hash;
    $sesh = md5($key);
    return $sesh;   
}
function update_session($usrid, $sesh) {
    $mysqli = new mysqli('localhost', 'root', 'root', 'accounts');
    $query = "UPDATE `users` SET `session` = '" 
        . $mysqli->real_escape_string($sesh) . "' WHERE `id` = '" 
        . $mysqli->real_escape_string($usrid) . "'"; 
    $mysqli->query($query);
    $mysqli->close();   
}
?>


在发出身份验证令牌之前,是否检查数据库中的电子邮件/密码是否返回true?这是正确的。我就是想不出一个安全的方法来为未注册的用户生成令牌。由于这是一个iOS项目,我试图阻止用户从web@jordavanvisit生成auth令牌。不管连接的是什么设备,只要从$POST中提取变量,然后对照数据库检查用户是否存在,然后创建会话。我将在下面发布一个示例。你认为“任何人都可以获得请求令牌”的问题是什么?那么,当它是iOS应用程序时,任何人都可以访问API并通过web发布。我知道不可能完全防止is,因为它毕竟是一个API。但我只是想找出阻止它的最佳方法@adelphus在发出身份验证令牌之前,你是否检查数据库中的电子邮件/密码是否返回true?这是正确的。我就是想不出一个安全的方法来为未注册的用户生成令牌。由于这是一个iOS项目,我试图阻止用户从web@jordavanvisit生成auth令牌。不管连接的是什么设备,只要从$POST中提取变量,然后对照数据库检查用户是否存在,然后创建会话。我将在下面发布一个示例。你认为“任何人都可以获得请求令牌”的问题是什么?那么,当它是iOS应用程序时,任何人都可以访问API并通过web发布。我知道不可能完全防止is,因为它毕竟是一个API。但我只是想找出阻止它的最佳方法@adelphus退出
$email
参数以防止SQL注入。Yea只是在你发布时在顶部添加注释。@sven阅读了我已经说过的评论,就像他说的那样,他已经有了…
strip_tags()
不是SQL退出函数
md5()
不是安全的密码哈希函数
extract()
使用攻击者定义的任意值污染全局变量范围,并增加使用未初始化变量的风险。用于创建令牌的“加密”功能在使用随机性方面的风险很低,并且它有一个严重的错误,将为每个人创建相同的令牌。注释将
md5()
与加密混淆。总而言之,我必须说,即使在最低级别上,这段代码看起来也非常危险,因为有太多基本的错误@JordanDavis哈希不是加密,它是一个单向函数。如果您想要一个唯一的随机会话ID获取随机字节或GUID,那么自行开发的方法往往很弱,请使用经过良好审查的方法。MD5不应用于新的工作,只需使用SHA256或更高版本,它同样易于使用和安全。如果要从密码创建密钥,请使用PBKDF2(基于密码的密钥派生函数2)并进行大量重复计数,这是当前的最佳做法。最后,攻击斯文是错误的,他的评论是有根据的zaph 55分钟前退出
$email
参数以防止SQL注入。Yea只是在顶部添加了注释,当你发布该注释时。@sven阅读了我已经说过的注释,就像他说的那样,他已经有了…
strip_tags()
不是SQL转义函数
md5()
不是安全的密码哈希函数
extract()
使用攻击者定义的任意值污染全局变量范围,并增加使用未初始化变量的风险。用于创建令牌的“加密”功能在使用随机性方面的风险很低,并且它有一个严重的错误,将为每个人创建相同的令牌。注释将
md5()
与加密混淆。总而言之,我必须说,即使在最低的lev上,这个代码看起来也非常危险