I have a problem with a file that involves session in PHP.
I have the following two php files:
confirm_save.php
<?php
include("confirm.php");
$_SESSION = array();
$token = $_SESSION['logout'];
if ($token && $_POST['token']==$token) {
if(isset($_COOKIE["id"]) && isset($_COOKIE["user"]) && isset($_COOKIE["pass"])) {
setcookie("id", '', strtotime( '-5 days' ), '/');
setcookie("user", '', strtotime( '-5 days' ), '/');
setcookie("pass", '', strtotime( '-5 days' ), '/');
}
// Destroy the session variables
session_destroy();
/*// Double check to see if their sessions exists
if(isset($_SESSION['username'])){
header("location: message.php?msg=Error:_Logout_Failed");
} else {
header("location: index.php");
exit();
}*/
header("location: index.php");
}
else {
// log potential CSRF attack.
}
unset($_SESSION["logout"]);
?>
Then, I have the confirm.php
<?php
session_start();
$token= md5(uniqid());
$_SESSION['logout'] = $token;
?>
<html>
<body>
<form method="post" action="confirm_save.php">
<input type="hidden" name="token" value="<?php echo $token; ?>" />
Do you really want to log out?
<input type="submit" value=" Yes " />
<input type="button" value=" No " onclick="history.go(-1);" />
</form>
</body>
</html>
After clicking "yes" in confirm.php, I get the following error:
Undefined index: logout in C:\wamp\www\confirm_save.php on line 4
Line 4 is
$token = $_SESSION['logout'];
I really do not know what the error may be.
You empty your $_SESSION by
$_SESSION = array();
and then try to fill $token
$token = $_SESSION['logout'];
with no value.
There shouldn't be a reason to empty $_SESSION, nor to define $token as you include confirm.php which also includes your $token with value
EDIT
Don't include confirm.php
But do:
<?php
session_start();
$token = $_SESSION['logout'];
if ($_POST['token']==$token) {
...
On line 3 you set $_SESSION to an empty array, meaning that $_SESSION['logout'] doesn't exist;
$_SESSION = array();
$token = $_SESSION['logout'];
I can't see a reason why you would want to empty the array, so you can remove that line.
You don't need the second line anyway. $token will be available as set in confirm.php.
Related
I have a form and when the users enter "Test" it should create a cookie and load the templates using require function. As soon as the cookie is enabled it will display the template. If the cookie expires it will require again the password. In other words, i if the password is "Test" i want to include that template for 12 hour to the user's browser before asking again for the password.
Below is what i am trying. More about cookies here
Problem is that the cookie idea is not working.
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$code = $_POST["SecretCode"];
}
if( $code === "test") {
$cookie_name = "user";
$cookie_value = "Cookie";
setcookie($cookie_name, $cookie_value, time() + (1000 * 10), "/"); // 86400 = 1 day
if(isset($_COOKIE[$cookie_name])) {
require_once 'template.php';
//echo 'cookie set:'.$_COOKIE[$cookie_name];
}
}?>
<form method="post" action='<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>'>
<input name="SecretCode" type="text" required>
<button>Check password</button>
</form>
Your cookie value within the $_COOKIE superglobal will not be populated until the next page request.
When you use setcookie the server will attempt to send a cookie to the client. If the cookie has not expired upon subsequent client requests, the client will present that cookie. Php will then use this value to populate the $_COOKIE superglobal.
In other words: setcookie('foo', 'bar', etc) does not immediately populate $_COOKIE['foo'].
You currently nest your template call like this:
if($code === "test") {
if(isset($_COOKIE[$cookie_name])) {
require_once 'template.php';
}
}
This requires that your secret is 'test' (from a form post) and that $_COOKIE['user'] is set. Your template therefore will not get included unless you submit your form with the correct value after the cookie has already been set (at least two successful form submissions and validations).
If you redirect after setcookie you can then rely moreso upon $_COOKIE. Do note that cookies can be spoofed:
<?php
$cookie_name = "user";
$cookie_value = "Cookie";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$secret = isset($_POST['secret']) ? $_POST['secret'] : null;
$forget = isset($_POST['forget']) ? $_POST['forget'] : null;
if($secret === "test") {
$cookie_expiry = time() + (24*60*60); // +1 day
setcookie($cookie_name, $cookie_value, $cookie_expiry , "/");
// Redirect here.
exit;
}
if($forget) {
$cookie_expiry = time() - (24*60*60); // -1 day
setcookie($cookie_name, '', $cookie_expiry , "/");
// Redirect here.
exit;
}
}
if(isset($_COOKIE[$cookie_name])) {
echo 'Cookie set.';
}
?>
<form method="post" action='<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>'>
<label for="secret">Secret:</label>
<input name="secret" type="text" required>
<input type="submit" value="Check in">
</form>
<form method="post">
<input type="submit" name="forget" value="Forget me">
</form>
This will also work:
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
$cookieName = 'User';
if (isset($_POST['SecretCode']) && ($_POST['SecretCode'] == 'test')) {
echo 'Password correct.<br>';
setcookie($cookieName,'Cookie',time()+86400,'/'); // 86400 = 1 day
echo 'Cookie was set.<br>';
echo 'Require template here.<br>';
} elseif (isset($_COOKIE[$cookieName])) {
echo 'Require template here as well.<br>';
echo 'Cookie value: ['.$_COOKIE[$cookieName].']<br>';
}
?>
<form method="post">
<input name="SecretCode" type="text" required>
<button>Check password</button>
</form>
Pretty simple setup: When the page is loading, a random session token is generated and saved in $_SESSION["token"]. A Form contains this token in a hidden input field. No problems until this point. I submit the form to the very same page (action="") and then I try to check if the $_SESSION["token"] is equal to the token that has been sent via POST. A variable is changed accordingly, and then I generate a new session token that replaces the old $_SESSION["token"] before the page loads again.
Problem is: The $_SESSION["token"] is changed again the moment the page is called (Before I can compare both SESSION and POST tokens) Therefore, both tokens never match. And I can't figure out WHY it changes. It's not the lines of code I wrote, because these are executed aswell, replacing the random token of unknown origin once again, before the page loads.
INDEX:
<?php
session_start();
date_default_timezone_set("Europe/Berlin");
$BASE_URL = "http://" . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
$form_valid = false;
if (isset($_POST["token"]) && isset($_SESSION["token"])) {
if ($_POST["token"] == $_SESSION["token"]) {
$form_valid = true;
}
}
//Set (new) session token
$token = bin2hex(random_bytes(10));
$_SESSION["token"] = $token;
//Load actual page
include ("/backend/admin.php");
?>
INCLUDED PAGE:
<?php echo "FORM VALID:"; var_dump($form_valid); ?>
<?php if (!isset($_SESSION["admin"]) || !$_SESSION["admin"]) { ?>
<form id="verify" method="POST" action="">
<label>Password</label>
<input type="password" name="access">
<input type="hidden" name="token" value="<?= $_SESSION['token'] ?>">
<input type="submit" value="Senden">
</form>
<?php } else { ?>
...
<?php } ?>
any help is appreciated. thank you.
There was a problem in your logic, session token updates every time regardless the form is submitted is not,
$token = bin2hex(random_bytes(10));
$_SESSION["token"] = $token
Try this,
<?php
session_start();
date_default_timezone_set("Europe/Berlin");
$BASE_URL = "http://" . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
$form_valid = false;
if(empty($_SESSION["token"] )){
$_SESSION["token"]= bin2hex(random_bytes(10));
}
if (isset($_POST["token"]) && isset($_SESSION["token"]))
{
if ($_POST["token"] == $_SESSION["token"]) {
$form_valid = true;
unset($_SESSION["token"]);
}
}
include ("/backend/admin.php");
?>
I'm getting frustated. Tried everything to logout users from my PHP page but it does not work the shoppingcart is still full and the user name is still there. My webpage is about a online shopping. The login works fine and I created a logout file with the following code
session_start();
session_destroy();
header('Location: login.php');
exit;
My login code is:
// get Members table
require './Model/Members.php';
$memberTable = new Members();
if (isset($_POST['data'])) {
// take security precautions: filter all incoming data!
$email = (isset($_POST['data']['email'])) ? strip_tags($_POST['data']['email']) : '';
$password = (isset($_POST['data']['password'])) ? strip_tags($_POST['data']['password']) : '';
if ($email && $password) {
$result = $memberTable->loginByName($email, $password);
if ($result) {
// store user info in session
$_SESSION['membro'] = $result;
$_SESSION['login'] = TRUE;
}
else {
$_SESSION['login'] = FALSE;
}
// redirect back home
header('Location: ?page=paginaprincipal');
exit;
}
}
my html from login page is:
<div class="content">
<br/>
<div class="product-list">
<h2>Login</h2>
<br/>
<b>Por favor, entre a sua informacao.</b><br/><br/>
<form action="?page=login" method="POST">
<p>
<label>Email: </label>
<input type="text" name="data[email]" />
<p>
<p>
<label>Password: </label>
<input type="password" name="data[password]" />
<p>
<p>
<input type="reset" name="data[clear]" value="Clear" class="button"/>
<input type="submit" name="data[submit]" value="Submit" class="button marL10"/>
<p>
</form>
</div><!-- product-list -->
</div>
Please help me to identify what am I doing wrong. I've tried a lot of different things from here but none of them works and I need this work to be done as soon as possible that's why my frustation :-(
Is there any chance that something has been stored in cookies? If so, try to clear them up as well.
How to clear them all:
how to delete all cookies of my website in php
A small guide: http://www.pontikis.net/blog/create-cookies-php-javascript
For the logout page this ought to do it.
session_start();
unset( $_SESSION['membro'] );
unset( $_SESSION['login'] );
/* cookies should be deleted when the session is destroyed anyway */
setcookie( session_id(), "", time() - 3600 );
session_unset();
session_destroy();
session_write_close();
session_start();
session_regenerate_id( true );
exit( header('Location: login.php') );
In response to your comments that it is still not working, I re-wrote some of your code as follows and tested using the code above ( though I emulated the $memberTable->loginByName with some static values and it worked. The session was completely destroyed each time and a new one regenerated so I'm not sure the problem lies in the logout script. If this continues to fail it might be worth looking into what cache-control headers are being set
<?php
require './Model/Members.php';
$memberTable = new Members();
if( isset( $_POST['data'] ) ) {
$data=$_POST['data'];
$email=isset( $data['email'] ) && !empty( $data['email'] ) ? trim( strip_tags( filter_var( $data['email'], FILTER_SANITIZE_EMAIL ) ) ) : false;
$password=isset( $data['password'] ) && !empty( $data['password'] ) ? trim( strip_tags( filter_var( $data['password'], FILTER_SANITIZE_STRING ) ) ) : false;
if ( $email && $password ) {
$result = $memberTable->loginByName( $email, $password );
if ( $result ) {
$_SESSION['membro'] = $result;
$_SESSION['login'] = TRUE;
} else {
$_SESSION['login'] = FALSE;
}
exit( header('location: ?page=paginaprincipal') );
}
}
?>
I am making a simple oauth site.
In index.php:
<?php
session_start();
if (empty($_SESSION['authentication']))
$_SESSION['authentication'] = 'pending';
?>
<html>
<form action="oauth.php" method="post">
<span>
<?php
echo $_SESSION['authentication'];
?>
</span>
<input type="hidden" name="action" value="authenticate">
<input type="submit" value="authenticate">
</form>
</html>
In oauth.php:
<?php
session_start();
if (isset($_POST['action']) and $_POST['action'] == 'authenticate') {
$url = $serverAuth ... ;
header('Location: ' . $url); //google oauth, it will come back to oauth.php
exit();
}
if (isset($_GET['code'])) {
$ch = curl_init($serverToken);
$result = curl_exec($ch);
$tokens = json_decode($result, true);
if (isset($tokens['access_token'])) {
$_SESSION['authentication'] = 'good';
$_SESSION['access_token'] = $tokens['access_token'];
} else {
$_SESSION['authentication'] = 'error';
}
header('Location: ./');
exit();
}
if (isset($_GET['error'])) {
if ($_GET['error'] == 'access_denied')
$_SESSION['authentication'] = 'denied';
else
$_SESSION['authentication'] = 'error';
header('Location: ./');
exit();
}
?>
I want to make the site like: by default, $_SESSION['authentication'] is "pending"; when I refresh the page, every session variables are gone, and $_SESSION['authentication'] reset to default. But I cannot reset $_SESSION at the beginning of index.php, because functions in oauth.php have header() to redirect to this page.
How to deal with it?
You must start the session on every single page that requires access to $_SESSION. Only destroy it when explicitly requested, e.g. on logout.
see: http://www.eat-drink-etc.com/
I have this code in the header of all the sites' pages:
<?php
session_start();
if (!isset($_SESSION['responsibility'])) {
//echo '{redirect="responsibility/message"}';
echo "<script type='text/javascript'>window.location = '{site_url}responsibility/message'</script>";
}?>
Redirecting to mydomain/responsibility/message if the user is a first time (or hasn't visited recently) visitor to the site.
In the message page I have the following:
<?php
session_start();
/*if (ini_get("session.use_cookies")) {
$params = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000,
$params["path"], $params["domain"],
$params["secure"], $params["httponly"]
);
}
$_SESSION = array();*/?>
function setcookielive($name, $value='', $expire=0, $path='', $domain='', $secure=false, $httponly=false) {
//set a cookie as usual, but ALSO add it to $_COOKIE so the current page load has access
$_COOKIE[$name] = $value;
return setcookie($name,$value,$expire,$path,$domain,$secure,$httponly);
}
if(isset($_POST['set'])) {
if(isset($_POST['remember'])) {
/*if(setcookielive("responsibility", "confirmed", time()+60*60*24*30*24, "/")) {
}*/
$_SESSION['responsibility'] = 'confirmed';
echo '{redirect="/"}';
}
else {
/*if(setcookielive("responsibility", "confirmed", time()+60*60*24, "/")) {
}*/
$_SESSION['responsibility'] = 'confirmed';
echo '{redirect="/"}';
}
}?>
The page uses a from input to enter the site:
<form method="post" action="">
<input type="hidden" name="set" value="set" />
<input type="hidden" name="remember" value="true" />
<input type="image" src="{site_url}images/elements/enter-btn.png" width="95" height="26" alt="Enter" value="Enter" />
</form>
Example: if a user goes to http://www.eat-drink-etc.com/articles/fi_europe_ni_2011
they will be redirected to the responsibility/message page. When enter is clicked the user is taken to the home page. (as specified)
How do I redirect to the originally targeted url??? eg. ../articles/fi_europe_ni_2011
Fisrtly, why are you performing the browser redirect through Javascript (client side) when you could do the same thing server side with a header("Location: $url;"); call?
<?php
ob_start();
session_start();
if (!isset($_SESSION['responsibility'])) {
ob_end_clean();
header("Location: $url; ");
exit;
}
// etc... you would need to call ob_end_flush(); before ending the page if you plan to have output here.
Something like that, to start with.
To answer your question: You would need to retrieve the current URL and store it as a session property before redirecting to the messages page. To amend my above example:
<?php
ob_start();
session_start();
$_SESSION['last_url'] = (!empty($_SERVER['HTTPS'])) ? "https://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'] : "http://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
// etc
You could then access this URL on the confirmation page by again performing a header redirect like this:
header("Location: {$_SESSION['last_url']}");
You could do:
<?php
session_start();
if (!isset($_SESSION['responsibility'])) {
header("Location: /responsibility/message?refer=" . urlencode($_SERVER["REQUEST_URI"]));
}?>
And on your responsibility page you do something like:
if(isset($_POST['set'])) {
if(isset($_POST['remember'])) {
$_SESSION['responsibility'] = 'confirmed';
if( isset($_GET['refer']) )
header("Location: " . $_GET['refer']);
}
}
You might need to add a few checks to the $_GET['refer'] so that it won't get abused but you get the idea