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>
Related
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 sure this is a basic question and I'm sure the answer is basic too - apologies if so, but I'm having trouble linking my practical example to the theory I've read.
I'm using the PHPAuth project for my site's authentication. The bit that's got me confused in the notes is the description for the login method that reads:
Authenticates a user with the system. Note: You need to take the
returned session hash and create the session cookie, the method does
not do this for you.
If a successful login returns:
Array ( [error] =>
[message] => You are now logged in.
[hash] => 374d0de4f97b96b6665c23aa0998dbae1f790fe6
[expire] => 0
)
What do I actually do with this information to allow the next page to see that a user is logged in?
<?php
require 'vendor/autoload.php';
include("dbconnect-user.php");
$config = new PHPAuth\Config($dbh);
$auth = new PHPAuth\Auth($dbh, $config);
if (!$auth->isLogged()) {
header('HTTP/1.0 403 Forbidden');
echo "Forbidden";
exit();
}
echo "you are logged in";
?>
I am assuming the above code will handle the session cookie as this is code is almost exactly as the example given by the PHPAuth project so specifically, I'm asking what is meant by the bold text in the above quote.
FYI, the class functions for checking the cooking look like this:
/**
* Returns is user logged in
* #return boolean
*/
public function isLogged() {
return (isset($_COOKIE[$this->config->cookie_name]) && $this->checkSession($_COOKIE[$this->config->cookie_name]));
}
/**
* Returns current session hash
* #return string
*/
public function getSessionHash(){
return $_COOKIE[$this->config->cookie_name];
}
My previous answer answers my question, but I'm posting this answer in the hope that it may help someone else using the PHPAuth project.
This is my login page:
<?php
require 'vendor/autoload.php';
include("dbconnect-user.php"); //this contains my own database connection code
$config = new PHPAuth\Config($dbh);
$auth = new PHPAuth\Auth($dbh, $config);
if ($auth->isLogged()) {
echo "You are already signed up and logged in";
exit();
}
$msg = null;
$showform = true;
if ($_SERVER["REQUEST_METHOD"] == "POST") {
//check for errors
if (empty($_POST["email"]) ||
empty($_POST["pwd"]) ) {
$msg = "All fields are required.";
} else { //all good - proceed
$result = $auth->login($_POST["email"], $_POST["pwd"]);
//check for success
if ($result["error"] == 1) {
$msg = $result["message"];
} else {
//success
$msg = $result["message"];
$showform = false;
setcookie($config->cookie_name, $result['hash'], time()+3600, "/"); //NOTE: the time can be set with config from the cookie_forget or cookie_remember settings in the PHPAuth config table
}
}
}
?>
<html>
<head></head>
<body>
<?php
if ($showform == true) { ?>
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>">
<div>
<label for="email">Email:</label>
<div>
<input type="email" name="email" id="email" placeholder="Enter email" value="<?php echo isset($_POST['email']) ? $_POST['email'] : ''; ?>">
</div>
</div>
<div>
<label for="pwd">Password:</label>
<div>
<input type="password" name="pwd" id="pwd" placeholder="Enter password">
</div>
</div>
<div>
<button type="submit" name="submit">Submit</button>
</div>
<?php echo $msg; ?>
</form><?php
} else {
echo $msg . '<br />';
}
?>
</body>
</html>
This is a secured page:
<?php
require 'vendor/autoload.php';
include("dbconnect-user.php"); //this contains my own database connection code
$config = new PHPAuth\Config($dbh);
$auth = new PHPAuth\Auth($dbh, $config);
if (!$auth->isLogged()) {
header('HTTP/1.0 403 Forbidden');
echo "Forbidden";
exit();
}
echo "You are logged in";
?>
And this is a logout script:
<?php
require 'vendor/autoload.php';
include("dbconnect-user.php"); //this contains my own database connection code
$config = new PHPAuth\Config($dbh);
$auth = new PHPAuth\Auth($dbh, $config);
echo $auth->logout($_COOKIE['authID']);
?>
The basic answer appears to be this:
Obviously, we need to create the session cookie. In this particular case, the cookie name needs to be the name stored in the config db, "authID".
To do this, I just need to use setcookie see http://php.net/manual/en/function.setcookie.php
In my testing example, on a successful login, I set the cookie and then redirect on a script page like this:
setcookie('authID', $_GET['h'], time() + (86400 * 30), "/");
header('Location: main.php');
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.
I am learning session handling while submitting form data between multiple php pages.
For simple example, I have a php form myform.php that asks the user to enter a password and directs to myaction.php. I want to start the session before the user enter the password. If he enters the password as 1234 within one minute, it displays "valid". If he enters the password after 1 minute, it should display "Session timeout".
Here is my code that doesn't work.
myfrom.php
<?php
session_start();
$_SESSION['start'] = time();
$_SESSION['expire'] = $_SESSION['start'] + (01 * 60);
?>
<html>
<form nmethod="post" action="myaction.php">
<input type="text" name="myvalue"/>
<input type="submit" value="SignIn" name="submit1">
</form>
</html>
myaction.php
<?php
if ($_POST['submit1'])
{
$v1 = "1234";
$v2 = $_POST['myvalue'];
$_SESSION['now'] = time();
if ($_SESSION['now'] > $_SESSION['expire'])
{
echo 'Session Timeout!';
header('refresh:05;Location: http://localhost/myform.php');
}
else if(($_SESSION['now'] <= $_SESSION['expire']) && ($v1==$v2))
echo 'Valid Password!';
else
echo 'Invalid password!';
}
?>
Where did I go wrong?
the first thing I think you have a typo
<form nmethod="post"
there is additional "n" before method, remove it .
the second thing you have to use start_session() whenever you want to use anything from session.
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