I have two PHP files:
1.php
<?php
... header("location: 2.php?id=1");
?>
2.php
<?php
... echo $_GET['id'];
?>
URL from 1.php to 2.php is: http://localhost/2.php?id=1
My question. Is it possible to validate where get method coming from and accept only if from coming 1.php. But if someone in address bar changing id values then ignore? Something with $_SERVER['HTTP_REFERER'] but i'm not sure
Is it possible to validate where get method coming from and accept only if from coming 1.php.
Not reliably.
But if someone in address bar changing id values then ignore?
Find something else to test against. (e.g. is this a user who is logged in and authorised to view the page with that id?).
Simple answer is no. $_SERVER['HTTP_REFERER'] is often disabled by browsers and is easily spoofed.
You can do someting close to your requirement:
<?php
//1.php
$id = 1;
$key = generateKeyBasedOnId($id);
header("location: 2.php?id=$id&key=$key");
?>
You can write generateKeyBasedOnId() function as you wanted to,
but you are the only one who should known the algorithm.
(For example return md5('my very secret'.$id.' string');
<?php
//2.php
if($_GET['key'] !== generatekeyBasedOnId($_GET['id'])) {
//error
}
?>
Of course, if someone copy paste the url 2.php?id=..&key=..., it will still work. You can hide key into cookies, but it is still easilly spoofable.
You can also generate random key, save it into database, read it in 2.php and if it exists, immediately delete it. So the key can be used only once. But if someone catch your header redirect, he still could (theoreticaly) take it and use it in different browser in different country ...
Related
I want to have a navigation bar that tells the user where they just came from.
Example: Homepage -> Post
But if they are in their posts manager and click on a post, I want it to say
Posts manager -> Post
I read that $_SERVER['HTTP_REFERER'] is not good enough to get the full url so that's not useful as I want the navigation bar all clickable
Any help is much appreciated!
I believe what you want is called breadcrumbs.
What to use for navigation chain storage is actually up to you. You might use even $_SERVER['HTTP_REFERER'] if you want, but that'd be unreliable as it's client-side. Usual way to store such chain is actual URI or session.
For example, you have such URI: http://www.example.com/post_manager/post
Then you can iterate through explode("/", $_SERVER["REQUEST_URI"]) to get each step.
That's basic explanation to guide you to a right direction. You can google alot of samples and snippets using keyword breadcrumbs.
On the topic of saving last visited location (the way to determine wether abonent came from manager or homepage): you can use session's variables to do that. Here's an example:
This way you can set a variable on your homepage:
<?php
session_start();
$_SESSION['previous_location'] = 'homepage';
?>
And then you just access it from another page:
<?php
$previous_location = $_SESSION['previous_location'];
?>
It's important to set session.save_path in your PHP configuration file or your sessions might get lost.
You could do it on the client side if you use the Javascript document.referrer property. However, a better solution may be to use the global session array.
if (!isset($_SESSION['referrer'])) {
$_SESSION['referrer'] = $current_uri;
} else {
$previous_uri = $_SESSION['referrer'];
$_SESSION['referrer'] = $current_uri;
}
The best solution IMO is to save the location into session, every time the user goes to a 'meaningful' page (that you want to be able to navigate back to via this feature), then simply use this array of, say, last 2 visited pages to pull up all the information. Simple and effective.
<?php
session_start();
$_SESSION['user_interactions'][] = $_SERVER['HTTP_REFERER'];
// get previous
$previous_page = end($_SESSION['user_interactions']);
// list all user interactions
foreach($_SESSION['user_interactions'] as $key => $value){
echo $value;
if(count($_SESSION['user_interactions'])-1 != $key) echo ">";
}
?>
I have index.php that include pages like
<?php
define('MyConst', TRUE);
include_once('template/header.php');
if (!empty($_GET['action'])) {
$action = $_GET['action'];
$action = basename($action);
include("template/$action.php");
} else {
include("template/main.php");
}
include_once('template/footer.php');
?>
With in a template directory I have main.php which has link to other pages like page1.php, page2.php.
Goto page 1
Goto page 2
How could I prevent users form accessing pages directly typing "http://mydomain.com/?action=page1" on the URL? And redirect them to main.php if they have done it?
You can not. What you want is simply not possible.
For the server side there is no way to know whether an URL is typed or clicked.
If I understand correctly, the thing you want is to prevent the user to access http://example.org/?action=page1 unless they came from http://example.org/?action=main. To do that, you must be able to detect whether they came from http://example.org/?action=main. The safest way to do that is to generate some random value that you associate to the users when they access http://example.org/?action=main and to check whether there is a correct value associated to the users when they want to access http://example.org/?action=page1. If not, they tried to access that page directly.
Check for HTTP_REFERER and if it is not pointing to right values (like your meny page) then redirect user.
Maybe you can try this, On your index.php :
session_start();
if(! isset($_GET['action']))
{
$_SESSION['pageAccess'] = true; # Set the key whatever you want
}
then under that script (we need that session_start() used twice) :
if(isset($_GET['action']))
{
if(! isset($_SESSION['pageAccess']) || ! $_SESSION['pageAccess'])
exit('There is no direct access allowed.');
}
Hope this help, have a nice day.
As per your Question:
There are two approaches that you can follow:
Use HTTP_REFFRER and check on desired page if User is coming from the page u wanted. IF he is accessing the direct URL then show him error page.
Use $_SESSION but this approach can be harmful as SESSION will always be there untill browser / instance closed.
So better to go for 1st approach.
And also as per Pehaa, you can not check id URL is typed
I have the following PHP script within a file named login.php
<?php
$ref = $_SERVER['HTTP_REFERER'];
if ($ref == 'http://example.com/dir/invalid.php' || $ref == 'http://www.example.com /dir/invalid.php') {
echo '
<div id="invalid">
TESTTESTTESTTESTTESTTESTTESTTEST
</div>
';
}
?>
I have deliberately went to the invalid.php page (which redirects using header() to login.php) and this div does not show up. Does it have something to do with the referrer not really being invalid.php or is there an issue with the script?
Thanks
I don't think the HTTP_REFERER is what you think it is. Namely, it is the page from which the user followed a link to the current page. However, it's very unreliable as we rely on the browser of the user to correctly report this value.
I would suggest the option I thought you needed, except that the only one I can think of you might doesn't really makes sense... (checking if the url matches a url that's not the current script)... so I do not see what you are trying to do.
As promised several ways to do what you want to achieve:
First off, I don't like this solution at all and really consider it ugly, but it's the one closest to what you where trying to do.
invalid.php
require 'login.php'; // we include the file instead of referring to it
login.php
if ($_SERVER['SCRIPT_NAME'] == 'invalid.php')
{
// do whatever
}
The main difference between what you did and what I did for the user will be that here the url bar will show that you're at invalid.php and not somewhere else. This also means that refreshing doesn't make the message go away.
A better solution in my opinion is the following:
In your script that logs a user in (checks the database and everything):
if (!valid_login()) // pseudo-code, obviously
{
$_SESSION['invalid_login'] = true;
header('Location: login.php');
// previously, we had something like this instead of the two lines above:
// header('Location: invalid.php');
}
in login.php
if (isset($_SESSION['invalid_login']) && $_SESSION['invalid_login'])
{
$_SESSION['invalid_login'] = false;
// do whatever
}
Of course, this should be done with proper session facilities like starting up the session in both those files. Instead of using session variables, you could include the file and use normal variables or send GET variables through the header request, but both those solutions share a problem: refreshing doesn't make the message disappear. However, if you were to move the code from the top file of the two above to login.php (if it's not already there, I don't know what file that actually is...) you could once again use normal variables instead of session variables and have a solution in which refreshing does make it go away. In this case, you might argue that you are cluttering your files with bussiness logic and presentation, but there are solutions to that (like keeping it in a separate file, and including it into login.php, moving the html to another file and including that one into login.php or both.
I have a form that submits to the same page. Now when it gets submitted and after it's processed I need it to have a unique query string.
So for example the user inputs some info then clicks submit, then the page saves the info on the server then the server spits it back out with a unique query string for that info.
If I try to set $_SERVER['QUERY_STRING'] it just hangs. Is there another way to do this?
Is it possible with a redirect?
EDIT, I'm going from mysite.com/ and the form action is on mysite.com/ and I want the browser to go to mysite.com/?blah
OK I tried putting this on my the top of my page with no luck
<?php
if ($_POST['data']) header('location: /?' . idFromDifferentFunction() );
?>
but it just keeps loading, I'm guessing it just redirects itself to death.
I hope you now understand what I'm trying to do
Chances are that your script is continuing to run after the code that says it should redirect. You also need to be more precise with the header:
<?php
if (isset($_POST['data'])) {
header('Location: /?' . idFromDifferentFunction() );
exit;
}
?>
If you use the code above, it will make the script exit which dumps the output and the browser will see the redirect (note the capital L in Location).
The key point is the exit following the redirect header. Without it, PHP is very likely going to continue working on whatever other code you're doing in the script.
It's not entirely clear what you're after, but I think you mean you want to go to a page with a unique value in the query string (the bit after the ?) once the processing is complete. Does this unique value need to actually reference something in the system (for a newly-created DB entry does it need to reference the ID of the new entry) or does it just have to be unique?
If it's the latter, you could just generate a random unique ID do the following:
header ('location: /path/to/script?id=' . uniqid ());
If it's the former, then replace the call to uniqid with the value of the database key.
The values in $_SERVER are set at runtime by PHP and should be considered read-only. Changing their values will have no meaningful effect.
$_SERVER['QUERY_STRING'] is part of PHP's globals. You should not be setting those variables, instead set it via a session and return it after submission.
If you are trying to redirect the user to a specific URL then use:
header('Location: mysite.com/bla/bla');
Writing to $_SERVER is pointless. It doesn't affect the client browsers in any way. If you want to change the query string displayed in the client browser, you'll have to use a 301/302 redirect using a header('Location: ...') call.
I want to do something but cant figure out how to do this (i m newbie in php)
suppose, i have a list of URL's which shows live with this preg_replace,
$html = preg_replace('/\s(\w+:\/\/)(\S+)/', ' GO ', $html);
my output is like
http://localhost/get.php?url=http://yahoo.com
its obvious that you can view that links at output page, now i want to hide them at front page and make them clickable and working
something like we can change links into variables and then call them by clicking and something works in backgroud which can perform same thing as we are clicking on the link at front page
ya it seems bit confusing :(
you could save the url into a $_SESSION vars and when some users click the link retrive the url from $_SESSION and redirect to it...
//page1 - parse, save link in session and print a call to page2
<?php
session_start();
$_SESSION['url'] = preg_replace('/\s(\w+:\/\/)(\S+)/', ' GO ', $html);
....
echo 'GO';
?>
//page2
<?php
session_start();
header('Location: '.$_SESSION['url']);
?>
If i undeerstood what you meant...
Obviously now I used $_SESSION['url'] as a single string, but you can use a multidimensional array intead...
UPDATE:
anyway is better if you use an array on script..
example: http://www.test.org/go.php?page=# (where # is a number)
<?php
$array=("http://www.google.com","http://stackoverfloc.com","ecc");
//you can add more contorl in if statement, like between etc...
if (is_numeric($_GET['page']) header('Location: '.$array[$_GET['page']]);
?>
I'm sorry, maybe I'm not understanding quite well, but, isn't best approch use an array for in side server and use another Get variable to do that?
for example ?link=yahoo
and then
find link in array of url?
BY the way, I'm using NoScript and reports me like a warning..
You build up links with looking like this:
yourdomain.com/redirector.ph?url=#
where # represents an identifier.
In redirector.php you check if you know that identifier and send the redirect HTTP Header:
header("Location: http://www.example.com/");
Important Note:
You may not send any data before sending the header and the code after sending it won't be executed.
Info
http://php.net/manual/en/function.header.php
EDIT
Using this header is not absolutely proper in regards to standard, but it's not too far off, as the response really is at another location.