我已经实现了一个在每个页面上运行的功能,我希望从未登录的用户进行限制。在他或她未登录的情况下,该功能会自动将访问者重定向到登录页面。
我想创建一个从外部服务器运行的PHP函数,并遍历许多设置URL(包含每个受保护站点的URL的数组),以查看它们是否被重定向。因此,我可以轻松确保每个页面上的保护是否正常运行。
怎么可以这样做?
感谢。
答案 0 :(得分:24)
$urls = array(
'http://www.apple.com/imac',
'http://www.google.com/'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
foreach($urls as $url) {
curl_setopt($ch, CURLOPT_URL, $url);
$out = curl_exec($ch);
// line endings is the wonkiest piece of this whole thing
$out = str_replace("\r", "", $out);
// only look at the headers
$headers_end = strpos($out, "\n\n");
if( $headers_end !== false ) {
$out = substr($out, 0, $headers_end);
}
$headers = explode("\n", $out);
foreach($headers as $header) {
if( substr($header, 0, 10) == "Location: " ) {
$target = substr($header, 10);
echo "[$url] redirects to [$target]<br>";
continue 2;
}
}
echo "[$url] does not redirect<br>";
}
答案 1 :(得分:4)
我在使用标题卷曲比较我的网址和网址后,使用curl并仅使用标题:
$url="http://google.com";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, '60'); // in seconds
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_NOBODY, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$res = curl_exec($ch);
if(curl_getinfo($ch)['url'] == $url){
$status = "not redirect";
}else {
$status = "redirect";
}
答案 2 :(得分:3)
您可以随时尝试添加:
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
因为302表示它已移动,允许curl调用跟随它并返回移动的url返回的内容。
答案 3 :(得分:1)
我不确定这是否真的有意义作为安全检查。
如果您担心直接调用文件而没有“用户是否已登录?”检查正在运行,您可以执行许多大型PHP项目所做的事情:在中央包含文件(进行安全检查的地方)中定义常量BOOTSTRAP_LOADED
或其他任何内容,并在每个文件中检查该常量是否为集。
测试很棒,安全测试甚至更好,但我不确定你想要发现什么样的缺陷?对我来说,这个想法感觉就像浪费时间,不会带来任何真正的额外安全性。
在die()
重定向后确保您的脚本header("Location:...")
。这对于阻止在header命令之后显示其他内容是至关重要的(顺便说一下,你的想法不会抓住一个丢失的die(),因为仍会发出重定向头...)
如果你真的想这样做,你也可以使用像wget
这样的工具,并提供一个网址列表。将结果提取到目录中,并检查(例如,通过查看应该相同的文件大小)每个页面是否包含登录对话框。只是添加另一个选项......
答案 4 :(得分:1)
您是否要检查HTTP代码以查看它是否为重定向?
$params = array('http' => array(
'method' => 'HEAD',
'ignore_errors' => true
));
$context = stream_context_create($params);
foreach(array('http://google.com', 'http://stackoverflow.com') as $url) {
$fp = fopen($url, 'rb', false, $context);
$result = stream_get_contents($fp);
if ($result === false) {
throw new Exception("Could not read data from {$url}");
} else if (! strstr($http_response_header[0], '301')) {
// Do something here
}
}
答案 5 :(得分:0)
您可以使用会话,如果未设置会话数组,则将网址重定向到登录页面。 。
答案 6 :(得分:0)
我修改了Adam Backstrom的答案并实施了chiborg建议。 (仅下载HEAD)。它还有一件事:它将检查重定向是在同一服务器的页面中还是在外面。示例:terra.com.br重定向到terra.com.br/portal。 PHP会像重定向那样考虑它,这是正确的。但我只想列出重定向到另一个URL的URL。我的英语不好,所以,如果有人发现了一些很难理解并可以编辑的内容,那么欢迎你。
function RedirectURL() {
$urls = array('http://www.terra.com.br/','http://www.areiaebrita.com.br/');
foreach ($urls as $url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// chiborg suggestion
curl_setopt($ch, CURLOPT_NOBODY, true);
// ================================
// READ URL
// ================================
curl_setopt($ch, CURLOPT_URL, $url);
$out = curl_exec($ch);
// line endings is the wonkiest piece of this whole thing
$out = str_replace("\r", "", $out);
echo $out;
$headers = explode("\n", $out);
foreach($headers as $header) {
if(substr(strtolower($header), 0, 9) == "location:") {
// read URL to check if redirect to somepage on the server or another one.
// terra.com.br redirect to terra.com.br/portal. it is valid.
// but areiaebrita.com.br redirect to bwnet.com.br, and this is invalid.
// what we want is to check if the address continues being terra.com.br or changes. if changes, prints on page.
// if contains http, we will check if changes url or not.
// some servers, to redirect to a folder available on it, redirect only citting the folder. Example: net11.com.br redirect only to /heiden
// only execute if have http on location
if ( strpos(strtolower($header), "http") !== false) {
$address = explode("/", $header);
print_r($address);
// $address['0'] = http
// $address['1'] =
// $address['2'] = www.terra.com.br
// $address['3'] = portal
echo "url (address from array) = " . $url . "<br>";
echo "address[2] = " . $address['2'] . "<br><br>";
// url: terra.com.br
// address['2'] = www.terra.com.br
// check if string terra.com.br is still available in www.terra.com.br. It indicates that server did not redirect to some page away from here.
if(strpos(strtolower($address['2']), strtolower($url)) !== false) {
echo "URL NOT REDIRECT";
} else {
// not the same. (areiaebrita)
echo "SORRY, URL REDIRECT WAS FOUND: " . $url;
}
}
}
}
}
}
答案 7 :(得分:0)
function unshorten_url($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $url);
$out = curl_exec($ch);
$real_url = $url;//default.. (if no redirect)
if (preg_match("/location: (.*)/i", $out, $redirect))
$real_url = $redirect[1];
if (strstr($real_url, "bit.ly"))//the redirect is another shortened url
$real_url = unshorten_url($real_url);
return $real_url;
}
答案 8 :(得分:0)
我刚刚做了一个检查URL是否存在的函数
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
function url_exists($url, $ch) {
curl_setopt($ch, CURLOPT_URL, $url);
$out = curl_exec($ch);
// line endings is the wonkiest piece of this whole thing
$out = str_replace("\r", "", $out);
// only look at the headers
$headers_end = strpos($out, "\n\n");
if( $headers_end !== false ) {
$out = substr($out, 0, $headers_end);
}
//echo $out."====<br>";
$headers = explode("\n", $out);
//echo "<pre>";
//print_r($headers);
foreach($headers as $header) {
//echo $header."---<br>";
if( strpos($header, 'HTTP/1.1 200 OK') !== false ) {
return true;
break;
}
}
}
现在,我使用了一组URL来检查URL是否存在,如下所示:
$my_url_array = array('http://howtocode.pk/result', 'http://google.com/jobssss', 'https://howtocode.pk/javascript-tutorial/', 'https://www.google.com/');
for($j = 0; $j < count($my_url_array); $j++){
if(url_exists($my_url_array[$j], $ch)){
echo 'This URL "'.$my_url_array[$j].'" exists. <br>';
}
}
答案 9 :(得分:0)
我希望它能为您提供帮助:
function checkRedirect($url)
{
$headers = get_headers($url);
if ($headers) {
if (isset($headers[0])) {
if ($headers[0] == 'HTTP/1.1 302 Found') {
//this is the URL where it's redirecting
return str_replace("Location: ", "", $headers[9]);
}
}
}
return false;
}
$isRedirect = checkRedirect($url);
if(!$isRedirect )
{
echo "URL Not Redirected";
}else{
echo "URL Redirected to: ".$isRedirect;
}
答案 10 :(得分:0)
使用 get_headers()
获取标头并检查 Location
是否设置要简单得多。
$urls = [
"https://example-1.com",
"https://example-2.com"
];
foreach ($urls as $key => $url) {
$is_redirect = does_url_redirect($url) ? 'yes' : 'no';
echo $url . ' is redirected: ' . $is_redirect . PHP_EOL;
}
function does_url_redirect($url){
$headers = get_headers($url, 1);
if (!empty($headers['Location'])) {
return true;
} else {
return false;
}
}
答案 11 :(得分:-2)
我无法理解你的问题。 您有一个包含URL的数组,并且您想知道用户是否来自其中一个列出的URL? 如果我理解你的任务是正确的:
$urls = array('http://url1.com','http://url2.ru','http://url3.org');
if(in_array($_SERVER['HTTP_REFERER'],$urls))
{
echo 'FROM ARRAY';
} else {
echo 'NOT FROM ARR';
}