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.
Related
I have a very simple php single page, that requires the user to insert a specific username and pass in order to access its contents.
It generates a cookie that allows the user to access that page for one day.
If the user is logged in, the list of contents appear. If it's not, it shows the form.
It is all inside a single index.php page.
This single "protected" page contains a form where the user can put some information and save it. After the user logs in, all the content is shown as intended. But when the user tries to submit that form and reloads the page (the new content should be added to that page), it gets kicked out and the information contained in the form gets lost, and it's not saved.
This are the specific parts of the index.php page:
<?php session_start(); ?>
<!DOCTYPE html>
[...]
<?php
if(isset($_POST['loguearse'])) {
$_SESSION['user']=strip_tags($_POST['user']);
$_SESSION['pass']=strip_tags($_POST['pass']);
if($_SESSION['user'] == 'myuser' && $_SESSION['pass'] == 'mypass') {
if (isset($_SESSION['user'])) {
session_start();
setcookie ("usuario",$_POST['user'], time()+24*60*60);
setcookie ("clave",$_POST['pass'], time()+24*60*60);
}
[HERE IT GOES THE CONTENT THAT WORKS OK IF I STRIP THE LOGIN CONTROL]
}
} else {
setcookie("usuario","");
setcookie("clave","");
echo '
<form method="post">
<div class="form-group">
<input type="text" class="form-control" name="user" id="user" placeholder="Usuario">
</div>
<div class="form-group">
<input type="password" class="form-control" name="pass" id="pass" placeholder="clave">
</div>
</div>
<div class="modal-footer">
<input type="submit" name="loguearse" class="btn btn-primary">
</div>
</div>
</form>
';
echo 'No puedes entrar sin poner la clave correcta!';
}
?>
My question is: How do I keep that user logged in and with an active session for 24 hours?
Your testing order is the problem here. You are originally testing for the POST variable, not the SESSION variable. Try this:
Test for logout to see if the user tried to logout. If so, delete the session.
Test for the session variables to indicate they're already logged in.
IF 1 and 2 are false, test for login. If so, initialize session.
It's the way you construct your if-conditions. Every time the user doesn't submit a post form you overwrite the cookie. The condition isset($_SESSION['user']) has to be on the highest level (at first) and then the post form check.
Also you run twice session_start(), one time is enough.
I use this for this exact thing and just include this in the header of any page.
<?php
#session_start();
// DB DEFINITIONS
require_once($_SERVER['DOCUMENT_ROOT'].'/includes/db.php');
$db = db_connect();
if(isset($_GET['logout'])){
session_unset();
session_destroy();
if (isset($_COOKIE['cookuhash']) && isset($_COOKIE['cookfhash'])){
setcookie("cookuhash", "", time()-2592000,"/");
setcookie("cookfhash", "", time()-2592000,"/");
$uhash=$db->real_escape_string($_COOKIE['cookuhash']);
$fhash=$db->real_escape_string($_COOKIE['cookfhash']);
$db->query("DELETE FROM tblsessions WHERE USER_HASH='$uhash' AND FORM_TOKEN='$fhash'");
}
header("Location: /index.php");
exit();
}
if(!isset($_SESSION['loggedIn'])){
$_SESSION['loggedIn']=false;
$_SESSION['username'] = 'Anonymous';
$_SESSION['userid'] = 0;
$_SESSION['userlevel'] = 0;
$_SESSION['formToken'] = sha1(microtime());
}
if (!$_SESSION['loggedIn'] && isset($_COOKIE['cookuhash']) && isset($_COOKIE['cookfhash'])){
$uhash=$db->real_escape_string($_COOKIE['cookuhash']);
$fhash=$db->real_escape_string($_COOKIE['cookfhash']);
$result = $db->prepare("SELECT u.id,uname, lvl, user_lvl_expires FROM tblusers u LEFT JOIN tblsessions s ON s.USER_ID=u.ID WHERE USER_HASH='$uhash' AND FORM_TOKEN='$fhash'");
$result->execute();
$result->bind_result($id,$uname,$ads,$lvl,$expires);
$result->store_result();
if($result->num_rows > 0){
while ($result->fetch()) {
$_SESSION['loggedIn']=true;
$_SESSION['username'] = $uname;
$_SESSION['userid'] = $id;
$_SESSION['userlevel'] = $lvl;
$_SESSION['expires'] = $expires;
$_SESSION['formToken'] = sha1(microtime());
}
}
}
?>
Then in any page, just check:
#session_start();
if((!isset($_SESSION['loggedIn']) || $_SESSION['loggedIn']==0) && !isset($_COOKIE['cookuhash'])){
header("Location: /login.php");
exit();
}
Hey guys am trying to determine if two minutes are over in php..I have an input box and a php script that checks if 5 seconds are over or not..What i need is when the user inserts the correct value i just want to display password is correct and you are now logged in with the existing token.
After 5 seconds i want to display the message like you cant login with this token id anymore.
But the problem is everytime am geting the message you are now logged in with the existing token after 5 seconds. its not showing up the message you cant login .....
The code i have used..
<?php
session_start();
$_SESSION['logintime'] = time();
$name = $_POST['fname'];
$tokenvalue = 'sample';
if($name != $tokenvalue) {
echo 'the token is incorrect<br>';
} else {
echo "the token is correct<br>";
}
if (time() > $_SESSION['logintime'] + 5) {
echo 'you cant login with this token id anymore<br>';
} else {
echo 'you are now logged in with the existing token';
}
Hope can i diplay the message you cant login with this token id anymore after 5 seconds ??..
Where am i doing wrong ??..Any help would be apreciated..Thanx
A PHP script is executed by the server. As soon as you see something in your browser, there is no action on the server anymore (at least in this script).
To accomplish what you are trying here, you need to use AJAX (asynchronous javascript and xml).
There are some things that are eglible in this case:
Hardcoded request after x-seconds with javascript (I would recommend using jQuery for this):
setTimeout(function(){$('#message').load('myScript.php');}, 5000);
You could use SSE (Sever-Sent Events), where you open a persistent connection to the server and push the event after x-seconds. There are good tutorials on HTML5rocks and MDN.
You could use only javascript, because the message will only be on the client side - you need to validate the time anyways, before you save a user input. For this you could also use jQuery:
setTimeout(function(){$('#message').html('you cant login with this token id anymore<br>');}, 5000);
Update: there are some things strange in your code (I will try to explain what I mean using comments):
<?php
session_start();
// you set the login, before you validate the users input
$_SESSION['logintime'] = time();
// thats okay, but actually not really necessary
$name = $_POST['fname'];
// thats okay for a test only :)
$tokenvalue = 'sample';
if($name != $tokenvalue) {
// you should use exit() or die() when the login fails to end the script
echo 'the token is incorrect<br>';
} else {
// first you use the word "token" now "password"
echo "the password is correct<br>";
}
if (time() > $_SESSION['logintime'] + 5) {
echo 'you cant login with this token id anymore<br>';
} else {
echo 'you are now logged in with the existing token';
}
Update2: Maybe this helps you - it does what you described in the question:
<html>
<head>
</head>
<body>
<?php
$tokenvalue = 'sample';
if(isset($_POST['token'])){
if($_POST['token'] === $tokenvalue) {
echo '<div id="success">The password is correct.<br>You are now logged in with the existing token.</div>';
}
}
?>
<form action="" method="post">
Token: <input type="text" name="token"><br>
<input type="submit" value="Submit">
</form>
<script>
if(typeof(document.getElementById('success')) != 'undefined') {
setTimeout(function(){document.getElementById('success').innerHTML = "You can't login with this token anymore."},5000);
}
</script>
</body>
</html>
I'm making a form for the users to fill, then I check their inputs after i 'clean'
function test_input($data)
{
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
then, after I check some parameters I create SESSIONS to echo those values later (1 time to let the user see and check if what they input is correct, then to send an email)
Everything works fine when I do it with MAMP, but when I upload everything to the HostGator's servers some SESSIONS are being deleted and some change values! Why is this happening? And why to SOME sessions and not all of them??
Also, I use $_SESSIONS because when I validate the inputs I do it like this:
<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method="post">
<input name='id' type='text'>
</form>
So I send the input data to the same page and check it, and if everything is right I create the SESSIONS and redirect to the next form.
I know exactly where are the SESSIONS being deleted and changed their values, but I don't know how to stop it! I don't know if it's my code or something with the server.
EDIT
Here's how I save the input of one session that it's value is being modified:
I get the ID form the user from another .php:
FIRST FORM: GETTING THE ID
<?php
$checkcode = $_POST["id"];
$query = "SELECT id FROM agents_id_pass WHERE id ='$checkcode'";
$res = mysqli_query($link, $query);
$nres = mysqli_num_rows($res);
$array = mysqli_fetch_array($res);
list($id) = $array;
if ($nres == 0){
header('Location: ../compra/compra_login_fail.php');
exit();
}
else{
session_start();
$_SESSION['id'] = $checkcode; //HERE I SER THE SESSION
$_SESSION['planilla_venta_1_session'] = 1;
mysqli_close($link);
header('Location: planilla_venta_1.php');
exit();
}
SECOND FORM: GETTING PERSONAL INFO FORM THE USER (NAME, ADDRESS, ETC..)
I'm gonna show you just the session that deletes itself
<?php
session_start();
if (!isset($_SESSION['id'])){
session_destroy();
}
else{
//destroy session after 15 mins
if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 900))
{
// last request was more than 15 minutes ago
session_unset(); // unset $_SESSION variable for the run-time
session_destroy(); // destroy session data in storage
}
$_SESSION['LAST_ACTIVITY'] = time(); // update last activity time stamp
//Avoid session fixasion, changing session's id every 5 mins.
ini_set('session.gc-maxlifetime', 300);
if (!isset($_SESSION['CREATED'])) {
$_SESSION['CREATED'] = time();
} else if (time() - $_SESSION['CREATED'] > 300) {
// session started more than 5 minutes ago
session_regenerate_id(true);// change session ID for the current session an
invalidate old session ID
$_SESSION['CREATED'] = time(); // update creation time
}
}
if ($_SERVER["REQUEST_METHOD"] == "POST")
{
$zip = test_input($_POST["zip"]);
if (empty($_POST["zip"])){
$zipErr = "Código Zip es requerido";
}
else{
$zip = test_input($_POST["zip"]);
// check if name only contains letters and whitespace
if (!preg_match("/^[0-9 ]*$/",$zip))
{
$zipErr = "Sólo se permiten números";
}
else{
$_SESSION['zip'] = $zip;
}
}
if(!isset($zipErr) && isset($_SESSION['zip'])
echo "<script>
window.location = 'planilla_venta_members.php'; //IF THERE IS NO ERROR AND THE SESSION IS SET -> REDIRECT TO THE NEXT FORM. ALL SESSIONS SET
</script>";
exit();
}
}
?>
<form name="sell_form" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method="post">
<td style="text-align:center"><input class="input" style="width:40px; margin-right:5px" type="input" name="zip" maxlength="5" value="<?php echo $_SESSION['zip'];?>">
<br>Zip*
</td>
All my sessions are created that way, so my question is, why would the server unset or change the value of some sessions???
I solved it! It turns out I was writing my code with php ver 5.5 and the server php configuration was with php 5.2, so I just updated it.
I have 3 pages:
index.php
login.php
display.php
index.php
Sets up AngularJS using the ngRoute module to navigate my pages.
login.php
Loaded by default and sets PHP $_SESSION variables.
display.php
Echos the contents of $_SESSION.
I navigate to display.php from login.php using a link setup with ngRoute.
Problem
display.php does not show $_SESSION variables no matter how many times I navigate to and from it. It will only display them if I manually navigate to the page such as refreshing the page or entering the address in the browser.
I know the php code is executed because I can echo other things to the screen it just doesn't access the $_SESSION variables.
Why is this?
I think i might see where your problem is. You try to access php session in your single page angularJS HTML templates am i right? like:
<div ng-repeat="n in <?php $_SESSION['someSessionArray'] ?>">
That is not how it works. Your $_SESSION will never be available in your templates.
What you can do, is use an ajax request for your login authentication and have that request give you a session id.
Then use that session id when starting your session in further ajax requests (as already mentioned).
Then, when you want to store something to the php session, access the data via ajax request and php service.
a VERY, VERY, VERY, simple Example:
inside getFromSession.php
session_start($_GET['session_id']);
$key = $_GET['key']
echo json_encode($_SESSION[$key]);
inside storeToSession.php
session_start($_GET['session_id']);
$key = $_GET['key'];
$value = $_GET['value'];
$_SESSION[$key] = $value;
inside your login.php
$user = yourAuthMechanism($_GET['username'],$_GET['password']);
if($user) {
session_start();
echo json_decode(array('status' => 'success','sid' => session_id()));
}
else { ... error handling
inside anywhere in your angular where you need to access session data:
$promise = $http.get('pathtoyourphp/getFromSession.php?key=foo');
$http.set('pathtoyourphp/getFromSession.php?key=bar&value=4');
// now use promise to acces the data you got from your service
In general, no reason exists, why AngularJS apps, which request
PHP-based server-side stuff, won't be able to read $_SESSION.
That said, please provide at least the core concepts of of your AngularJS code, so we can provide further details.
Additionally, put just this in display.php:
<?
echo __FILE__
. '<br />' . date( DATE_RFC822 )
. '<br />' . var_dump( $_SESSION )
;
// intentionally skipped dangerous closing PHP-tag
Now run your AngularJS app and tell what comes out.
Make sure you start the session before reading the SESSION variables.
<?php
session_start();
echo $_SESSION["user9"];
?>
I don't think you're looking for angularJS.
I think you're looking for something more like this.
index.php:
<html>
<header>
<title>Login</title>
</header>
<body>
<form method="POST" action="login.php">
<input type="username" name="username" placeholder="username" />
<input type="password" name="password" placeholder="password" />
<input type="submit" value="Login" />
</form>
</body>
</html>
login.php
<?php
session_start();
if(empty($_POST)) {
die("You don't have permission to be here.");
} elseif(empty($_POST['username']) or empty($_POST['password'])) {
die("All fields are required.");
}
$username = "admin";
$password = "password";
if($_POST['password'] == $password && $_POST['username'] == $username) {
$_SESSION['loggedIn'] == "true";
header("Location: show.php");
} else {
die("Invalid login");
}
?>
show.php
<?php
if($_SESSION['loggedIn'] == "true") {
echo "You are logged in";
} else {
die("You don't have permission to be here.");
}
?>
I'm making a login system with php, and when I submit the correct information, it set's a cookie. the form action sends to the same page, wich has an isset cookie verification on top, but since cookies need a refresh after they're set, you need to refresh page another time so it can notice that cookies are there.
what's a workaround for it? here's my code (where username and password are "admin" just as a placeholder. when I get the system working, I'll pull values from database.)
<?php
if(isset($_COOKIE['user']))
{
echo "Hello, administrator.<br />";
echo "<a href=?logout=yes>logout</a>";
if(isset($_GET['logout']))
{
setcookie("user", $_POST['username'], time() - 3600);
}
}
else
{
if (isset($_POST['submit']))
{
if (($_POST['username']=="admin")&&($_POST['password']=="admin"))
{
setcookie("user", $_POST['username'], time() + 3600);
}
else
{
echo "empty field or wrong user/pass.";
}
}
else
{
echo "nothing submitted. show form.";
}
}
?>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
<table border="0">
<tr><td colspan=2><h1>Login</h1></td></tr>
<tr><td>Username:</td><td>
<input type="text" name="username" maxlength="40">
</td></tr>
<tr><td>Password:</td><td>
<input type="password" name="password" maxlength="50">
</td></tr>
<tr><td colspan="2" align="right">
<input type="submit" name="submit" value="Login">
</td></tr>
</table>
</form>
Unless you absolutely need to use a custom cookie, I would suggest to use the $_SESSION global instead. $_SESSION data is available as soon as you set it. But its more important feature is that the data is not stored on the client. What that mean in plain is that the user can never access its data. So it is harder to hack your login system. With a cookie, as other have pointed out, anybody can read and edit the data!
session_start();
if (isset($_GET['logout']))
{
unset($_SESSION['username']);
}
if ($_SESSION['username'] == 'admin')
{
echo "hello admin!";
}
else if (($_POST['username']=="admin")&&($_POST['password']=="admin"))
{
$_SESSION['username'] = $_POST['username'];
}
To use the $_SESSION globals, you need to put session_start() at the beginning of your script (before sending any data). It should solve your problem of redirection at the same time. Note that behind the scene, $_SESSION use a small cookie, but you don't really have to think about it. It only contain a small id.
more information on session
http://www.php.net/manual/en/book.session.php
PS : to be honest, I would still use a redirect here. When you POST a form and press the back button, the browser ask you to send the data again and its annoying. Using a redirect with header("Location: " . $newUrl); remove that annoyance. But just my 2 cents.
$loggedin = false;
if(isset($_POST['submit'])) {
// Do login checking and set cookies
$loggedin = true; // if the case
}else if(isset($_COOKIE['username']) && isset($_COOKIE['password'])) {
// Check if valid login
$loggedin = true; // if the case
}else{
// They are not logged in.
}
Then use the veriable $loggedin to see if they are logged in. I suggest making a user class though to handle this, so do you keep using the same code over and over again in your files.
You can make your own function to set cookies, ie:
function my_setcookie($name,$value,$expire){
$_COOKIE[$name] = $value;
return setcookie($name,$value,$expire);
}
But better idea is to redirect user after successful 'POST' request, so if the page is refreshed, browser won't complain about resending POST data.