因此,我目前正在学习PHP编程课程,最后我进入了身份验证和授权的领域。
因此,在本书中,我们首先限制了授予所有帐户访问权限的页面,您可以在其中更新和删除所有帐户。我们首先定义常量:
define('VALID_USERNAME', '');
define('VALID_PASSWORD', '');
为了方便起见,我只是将它们放在空字符串中。
一切顺利,弹出询问用户名和密码的对话框。但是,当我输入空字符串时,对话框会继续弹出,好像密码输入错误,或者根本不输入密码。即使当我用真实的字符串定义用户名和密码时,也会发生这种情况。
这是我的那部分代码:
if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW'])) {
header('http/1.1 401 Unauthorized');
header('WWW-Authenticate: Basic realm="Wonder Penguin"');
} else {
if (($_SERVER['PHP_AUTH_USER'] != VALID_USERNAME) ||
($_SERVER['PHP_AUTH_PW'] != VALID_PASSWORD)) {
header('http/1.1 401 Unauthorized');
header('WWW-Authenticate: Basic realm="Wonder Penguin"');
}
}
[如果您想知道为什么我不使用exit()函数来防止人们点击cancel来绕过身份验证并进入更新页面。我这样做是为了让我的老师可以为我最后创建的该页面评分。
我累了如何解决:
我测试过是否通过使用echo函数正确定义了有效的用户名和密码。
echo VALID_USERNAME;
echo VALID_PASSWORD;
它会弹出我定义的样子。因此从理论上讲,我认为我定义正确。
我试图用单引号,双引号和无引号编写define函数。这本书要我写这样的函数:
define(VALID_USERNAME, "admin");
define(VALID_PASSWORD, "password");
但是,当我尝试在此处定义未定义的常量时,这会引发错误。
var_dump($_SERVER);
结果:
array(37) {
["REDIRECT_HANDLER"]=> string(23) "application/x-httpd-php"
["REDIRECT_STATUS"]=> string(3) "200"
["HTTP_HOST"]=> string(20) "patti-bee2.dcccd.edu"
["HTTP_CONNECTION"]=> string(10) "keep-alive"
["HTTP_ACCEPT"]=> string(74) "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
["HTTP_USER_AGENT"]=> string(108) "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36"
["HTTP_ACCEPT_ENCODING"]=> string(17) "gzip,deflate,sdch"
["HTTP_ACCEPT_LANGUAGE"]=> string(14) "en-US,en;q=0.8"
["HTTP_COOKIE"]=> string(217) "__qca=P0-630369357-1378011844686; __utma=198331962.264424896.1377179965.1382812794.1384740700.12; __utmc=198331962; __utmz=198331962.1381981575.8.4.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided)"
["PATH"]=> string(135) "C:\Program Files (x86)\PHP\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;c:\php;"
["SystemRoot"]=> string(10) "C:\Windows"
["COMSPEC"]=> string(27) "C:\Windows\system32\cmd.exe"
["PATHEXT"]=> string(53) ".COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC"
["WINDIR"]=> string(10) "C:\Windows"
["SERVER_SIGNATURE"]=> string(0) ""
["SERVER_SOFTWARE"]=> string(21) "Apache/2.2.22 (Win32)"
["SERVER_NAME"]=> string(20) "patti-bee2.dcccd.edu"
["SERVER_ADDR"]=> string(14) "144.162.99.193"
["SERVER_PORT"]=> string(2) "80"
["REMOTE_ADDR"]=> string(11) "99.7.247.36"
["DOCUMENT_ROOT"]=> string(66) "C:/Program Files (x86)/Apache Software Foundation/Apache2.2/htdocs"
["SERVER_ADMIN"]=> string(16) "[email protected]"
["SCRIPT_FILENAME"]=> string(106) "C:\Program Files (x86)\Apache Software Foundation\Apache2.2\htdocs\Coleman\Wonder Penguin\PHP\show_all.php"
["REMOTE_PORT"]=> string(5) "54619"
["REDIRECT_URL"]=> string(40) "/coleman/wonder penguin/php/show_all.php"
["GATEWAY_INTERFACE"]=> string(7) "CGI/1.1"
["SERVER_PROTOCOL"]=> string(8) "HTTP/1.1"
["REQUEST_METHOD"]=> string(3) "GET"
["QUERY_STRING"]=> string(0) ""
["REQUEST_URI"]=> string(42) "/coleman/wonder%20penguin/php/show_all.php"
["SCRIPT_NAME"]=> string(40) "/coleman/wonder penguin/php/show_all.php"
["ORIG_SCRIPT_FILENAME"]=> string(18) "C:/PHP/php-cgi.exe"
["ORIG_PATH_INFO"]=> string(40) "/coleman/wonder penguin/php/show_all.php"
["ORIG_PATH_TRANSLATED"]=> string(106) "C:\Program Files (x86)\Apache Software Foundation\Apache2.2\htdocs\Coleman\Wonder Penguin\PHP\show_all.php"
["ORIG_SCRIPT_NAME"]=> string(16) "/php/php-cgi.exe"
["PHP_SELF"]=> string(40) "/coleman/wonder penguin/php/show_all.php"
["REQUEST_TIME"]=> int(1385432192)
}
此时,我几乎已经将其直接从书中复制了出来。我在做什么错?
如果您想亲自尝试,这里是link to my site。
使用下面的代码获得最佳效果,例如
定义(VALID_USERNAME,“管理员”);define(VALID_PASSWORD,“ password”);
如果((($ _SERVER ['PHP_AUTH_USER']!= VALID_USERNAME)||($ _SERVER ['PHP_AUTH_PW']!= VALID_PASSWORD))[
header('WWW-Authenticate: Basic realm="Wonder Penguin"');
header('HTTP/1.0 401 Unauthorized');
exit;}
尝试一下
define('VALID_USERNAME', '');
define('VALID_PASSWORD', '');
if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW']))
{
header('http/1.1 401 Unauthorized');
header('WWW-Authenticate: Basic realm="Wonder Penguin"');
echo "Fail";
}
else
{
if (($_SERVER['PHP_AUTH_USER'] != VALID_USERNAME) ||
($_SERVER['PHP_AUTH_PW'] != VALID_PASSWORD))
{
header('http/1.1 401 Unauthorized');
header('WWW-Authenticate: Basic realm="Wonder Penguin"');
echo "Fail";
}
else
{
echo "SUccess";
}
}
这种全局变量用户名和登录状态是存储在会话中,所以我们可以全局使用,我更喜欢存储在会话中,而不是将其定义为常量
我知道我不是专家,也不擅长清楚地解释事物,但据我所知,问题在于如何使用基本身份验证以及将基本身份验证的标头放置在哪里(对我来说,请不要多余地放置它。):
以下代码可以帮助您进行基本身份验证:
包含用户名和密码等凭据。我不建议出于安全目的使用define()。
if(isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW']))
{
$valid_user = 'admin';
$valid_password = 'password';
if($_SERVER['PHP_AUTH_USER'] == $valid_user && $_SERVER['PHP_AUTH_PW'] == $valid_password)
{
$response = array('Response' => true,
'Message' => 'Welcome! ' . $valid_user);
$result = json_encode($response);
echo $result;
}
else
{
$response = array('Response' => false,
'Message' => 'User and Password does not match!');
$result = json_encode($response);
echo $result;
exit();
}
}
else
{
header('WWW-Authenticate: Basic realm="Wonder Penguin"');
header('HTTP/1.0 401 Unauthorized');
$response = array('Response' => false,
'Message' => '401 Unauthorized!');
$result = json_encode($response);
echo $result;
exit();
}
仅此而已,喜欢学习!
从php5.6开始,您可以在编译时使用const。这意味着您不能在运行时在内部条件中分配它们,就像使用define。
一样。const VALID_USERNAME = "admin"; // global
const VALID_PASSWORD = "password"; // global
class CREDENTIALS {
const VALID_USERNAME = "admin"; // not global
const VALID_PASSWORD = "password"; // not global
}
if(isset($_SERVER['SOMETHING'])){
const VALID_USERNAME = "admin"; // won't work
const VALID_PASSWORD = "password"; // won't work
}
if(isset($_SERVER['SOMETHING'])){
define("VALID_USERNAME","admin"); // works
define("VALID_PASSWORD","password"); // works
}
echo CREDENTIALS::VALID_USERNAME; // "admin"
echo CREDENTIALS::VALID_PASSWORD; // "password"
if(!defined("VALID_USERNAME")){
echo "the constant VALID_USERNAME is not defined";
}
或者如果您想创建一个数组
常量作为数组class CREDENTIALS { const ARR = [ VALID_USERNAME => "admin", VALID_PASSWORD => "password" ] } echo CREDENTIALS::ARR['VALID_USERNAME']; // "admin", echo CREDENTIALS::ARR['VALID_PASSWORD']; // "password"
自php7起,您现在还可以define
始终在当前名称空间中定义常量,而使用define则必须始终使用完整的名称空间名称define(ARR, [ "VALID_USERNAME" => "admin", "VALID_PASSWORD" => "password" ]); echo ARR["VALID_USERNAME"]; // "admin" echo ARR["VALID_PASSWORD"]; // "password"
如果使用的是名称空间,const
namespace SOME\NAME\SPACE;
const VALID_USERNAME = "admin";
const VALID_PASSWORD = "password";
define("SOME\NAME\SPACE\VALID_USERNAME", "admin");
define("SOME\NAME\SPACE\VALID_PASSWORD", "password");
也许是因为您正在寻找使用OR。您是说用户名无效或密码无效,然后显示401。尝试将其设为&&代替吗?这样,他们必须具有确切的用户名和密码。
这很简单:如果您以编程方式设置用户名和密码,请尝试执行此操作(如果使用登录页面!)