Not how to create a session timeout in Php, but where? - php

My boss purchased some web-based software (PC Repair Tracker...it's amazing), and put me in charge of installing it on our domain, configuring the database, the pricing, the look and feel (html/css). the ticketing system, etc. It's basically a template that you purchase and fully customize to meet your needs.
Configuring it wasn't too bad, even considering I am still a novice with PHP MySQL, etc. My boss requested I "make it logout after a certain time" because it contains sensitive info, and repairs are tracked by employee to know who to go to when information is needed on a device that's at our store.
What he means is that I need to write a timeout function.
The problem is not just creating the timeout function, but knowing where to put it? There are probably close to 100 files the website folder, each one of them a .php file (except for css stuff and images). Do I use the intuitive approach and start with login.php?
And how do I know what to call my variables?
The interface begins at the landing page with a login form. I don't think I would want to start at login.php, because they need to at least be logged in.
I installed FirePHP for Firefox and I noticed a function being called: It says:
GET ajaxhelpers.php?func=refreshnotifications
It pops up every minute or so. When I find that .php file, it's very short, and says:
if (array_key_exists('func',$_REQUEST)) {
$func = $_REQUEST['func'];
} else {
$func = "";
}
function nothing() {
}
function refreshnotifications() {
require("deps.php");
require_once("common.php");
echo pcrtnotify();
}
switch($func) {
default:
nothing();
break;
case "refreshnotifications":
refreshnotifications();
break;
}
?>
I also found a "validate.php" that sends a user to the login page. Could I put a function there?
<?php
include("deps.php");
$validated = false;
//Use $_COOKIE to get the cookie data . same usage as $_POST
if(isset($_COOKIE["username"])&&isset($_COOKIE["password"])) {
$user = $_COOKIE["username"];
$pass = $_COOKIE["password"];
//Begin validation code
if(isset($passwords[$user])) if($passwords[$user]== $pass) $validated = true;
//End validation code
}
if($validated) {
//Ok; don.t need to do anything
} else {
//Make user go to login page
die("please login");
exit;
}
?>
Is this a good start? Sorry for the lengthy question. I'm not asking for homework advice or anything. I'm just trying to learn php in a crash course fashion because he's going to want results yesterday. Lol.
It seems like I could put a condition in there that says,
if($validated && idle_time > time_allowed) {
go to logout.php
}
But then again, I'm a php noob.

Search for session_start() and before that line add the following
session_set_cookie_params(3600,"/");
The number is in seconds. So 3600 represents one hour.

Alright. I did some more digging, and I discovered a validate2.php, and logout.php file. Well, I already knew logout.php existed, I just looked closer at the code.
Inside, it contains conditional logic for a variable, $cookiedomain, and it also contained values for when a cookie expired for the user. If I'm saying all of this wrong, forgive me. I'm still learning php. Just trying to apply fundamental logic to all this.
So, what the validate.php file eventually does is check if the boolean $validated is true. If it's true, it continues and give you the ability to refresh. If it is not validated, you are presented with a tiny button on the screen that says "Please login".
1) This was incredibly sloppy and hard to find.
2) The time was set to 10 hours.
So, for testing purposes, I set the numbers to 20 in validate.php and logout.php, like so (I'm using the new value - 120 - in my code because I changed it since 20 seconds was too short obviously):
login.php
if(isset($cookiedomain)) {
setcookie("username", $user, time()+120, "/","$cookiedomain");
setcookie("password", $pass, time()+120, "/","$cookiedomain");
} else {
setcookie("username", $user, time()+120, "/");
setcookie("password", $pass, time()+120, "/");
}
logout.php
if(isset($cookiedomain)) {
setcookie("username", $user, time()-120, "/","$cookiedomain");
setcookie("password", $pass, time()-120, "/","$cookiedomain");
} else {
setcookie("username", $user, time()-120, "/");
setcookie("password", $pass, time()-120, "/");
}
validate2.php
if($validated) {
//Ok. don't need to do anything
} else {
//Make user go to login page
echo '<script type ="text/javascript">alert("Sorry, ' . $user . ', but you have been logged out due to inactivity.");</script>';
exit;
}
It's still not printing the user name, just a ' ', so I still need to work on that. The ugly button is gone, and it gives the user a nice, obvious notification that they've been logged out.
I would like to make the button redirect, so now on to working that part out.

Related

Error in executing tempdata

Form.php(controller)
public function dispdata()
{
$result['data']=$this->Form_model->displayrecords();
$this->load->view('display_records',$result);
if (!$this->session->userdata('ci_session'))
{
redirect('Form/login');
}
else
{
$this->session->set_tempdata('item',$result,5);
}
}
display_records(view)
<?php
if($this->session->tempdata('item')){
redirect('Form/login');
}
?>
im trying to work with the tempdata concept. i have a registration form where i have stored all the registered details in the datbase and those store details of database i have displayed
it in the view page.
how that i have displayed all the database details in a view page that view page im trying to display only for 5sec and after 5sec it should redirect to the login page. i have tried with the above code but its not working please can anyone tel me where im going wrong ?
The tempdata feature for sessions only affects how long the data is allowed to be stored. The removal of the data, after 5 seconds in your case, won't cause anything else to change on the page.
As far as I can tell you don't need tempdata at all. Try this to see if you get the behavior you want.
public function dispdata()
{
if (!$this->session->userdata('ci_session'))
{
redirect('Form/login');
}
$result['data']=$this->Form_model->displayrecords();
$this->load->view('display_records',$result);
// sleep for 5 seconds
sleep(5);
redirect('Form/login');
}
Why did I remove the else from your code? Because redirect does not return - it ends script execution. So, when the if evaluates to true and the redirect executes this script is done.

How can I persist data for a redirect with CodeIgniter?

I'm attempting to validate a users login attempt and inform them that
Their username is wrong or
their password is wrong (because I personally hate with a blind fury when a website doesn't inform me WHICH it is but that's beside the point).
I've read a lot of SO posts on this issue but the ones I've found are years old and I'm dealing with CodeIgniter 3.0.1.
This is the code that I have in place. I'm using Eclipse PDT to as my IDE and I like it quite a bit (but that's getting off track) so I've been able to step through the execution and watch as it just fails completely.
IF (!$this->User->login( //Testing shows this works fine - the SWITCH statement gets executed as it should and the BADUSERNAME case is followed through.
addslashes(strtolower($this->input->post('username', TRUE))),
addslashes($this->input->post('password', TRUE)),
$this->getIP())){
SWITCH($this->User->ID){
CASE 'BADUSERNAME':
$this->session->set_flashdata('user_msg', 'Invalid Username');
BREAK;
CASE 'BADPASSWORD':
$this->session->set_flashdata('user_msg', 'Invalid Password');
BREAK;
CASE 'ALREADYLOGGEDIN':
$this->session->set_flashdata('user_msg', 'You are logged in elsewhere.');
BREAK;
DEFAULT:
$this->session->set_flashdata('user_msg', 'Something has gone terribly wrong. Please try logging in again.');
BREAK;
}
redirect(base_url());
}
Then a bit further down I load the header, body, and footer views - The body is where the error message should be displayed but it's not..
<div id="contentarea">
<div class="container">
<?PHP
ECHO $this->session->flashdata('show_validation') ? validation_errors() : '';
$error = $this->session->flashdata('user_msg'); //This is where it's supposed to get it...
IF ($error) //And this is where it's supposed to show it...
ECHO "<div class='error'>$error</div>";
?> //But the value is wiped so it only ever grabs NULL.
I've followed the path of execution after calling the redirect after setting the flash data and I've noticed that after the redirect finishes it's chain of execution, it calls exit;.
Then everything loads again from the index.php file, and when Session finally pops up... the value 'user_msg' is nowhere to be found.
So clearly I'm doing something wrong here - what am I doing wrong here? Will the flash_data only persist until that redirect is called? Even the session_data values (calling $this->session->value = 'some arbitrary user message' fails to persist).
How can I persist the message for the next time the body element is loaded so that it can tell the user "Hey, didn't find you" or "Hey, your password wasn't right"?
EDIT 1
So it turns out I do not need to redirect for what I am doing as POSTing (submitting the user name and password) handles that for me.
I'm going to leave the question here for anyone else who may need it answered though - perhaps the answer is simply that Flash data just doesn't survive a redirect?
Flashed data is only available for the next http request, if you reload the page a second time, data is gone.
To persist data in the session, you want to set the variable in the session.
Codeigniter
Adding Session Data
Let’s say a particular user logs into your site. Once authenticated, you could add their username and e-mail address to the session, making that data globally available to you without having to run a database query when you need it.
You can simply assign data to the $_SESSION array, as with any other variable. Or as a property of $this->session.
Alternatively, the old method of assigning it as “userdata” is also available. That however passing an array containing your new data to the set_userdata() method:
$this->session->set_userdata($array);
$this->session->set_userdata('username', 'username is wrong');
in the view
$this -> session ->userdata('username');
or
$this ->session -> username;
Reference Session Library Codeigniter.
hope this help.
All you have to do is use $this->session->keep_flashdata('user_msg') with $this->session->unset_userdata('user_msg')
here is the solution (view file)
<?php
$error = $this->session->flashdata('user_msg');
if (isset($error)) {
echo '<div class="error">' . $error . '</div>';
$this->session->unset_userdata('user_msg');
}
?>
After that in your controller construct function (In that controller where you redirecting)
public function __construct() {
parent::__construct();
//.....
$this->session->keep_flashdata('user_msg');
}
I had same problem and this works. do not forget to clear cache when try or try in different browser
You can use codeigniter's flashdata to display errors separately.
This is what I usually use.
Controller:
$errors = array();
foreach ($this->input->post() as $key => $value){
$errors[$key] = form_error($key);
};
$response['errors'] = array_filter($errors);
$this->session->set_flashdata($response['errors']);
redirect('your-page', 'refresh');
And the to display the errors use
<?php echo $this->session->flashdata('field_name'); ?>

Wordpress: when I added an authenticate filter, the logout process got really slow

I need to sync my WP with an ERP right after the login button is pressed. Basically you type username and password, before Wordpress does what it has to do I perform a few things.
So basically I did this:
function intercetta_login($user, $username, $password) {
global $ecommerceFrontend;
$ecommerceFrontend->intercetta_login($username);
return $user;
}
add_filter( 'authenticate', 'intercetta_login', 30, 3 );
Everything works as expected, I'm completely happy with it. The problem is logging out. When this filter is ON logout takes about two minutes. When I turn this off it takes a couple of seconds (based on connection speed I don't mind counting seconds, it's just that 2 minutes makes me think of a problem).
I made an other test:
function intercetta_login($user) {
$username = $user->data->user_login;
global $ecommerceFrontend;
$ecommerceFrontend->intercetta_login($username);
return $user;
}
add_filter('wp_authenticate_user', 'intercetta_login', 10, 1);
In this case the logout process looks fine, but this is not working as I want: if a user exist on the ERP (but it doesn't exist on Wordpress) the function ends up with a login error (user dosn't exist). I believe it's happening later on, I need my to update things before Wordpress does the normal autentication.
So question number 1 is: why my first solution works, but takes forever to logout?
Question number 2 is: why solution 2 have a wrong timing? should I use this by fixing the timing?
Thanks in advance guys!
Possibly I found a workaround. The logoff was very slow because my function was called also during logout. I didn't knew that, but basically I was entering my loop also during logout, and that was causing the issue. So basically I edited the code this way around:
function intercetta_login($user, $username, $password) {
if (!$_GET['loggedout']) {
global $ecommerceFrontend;
$ecommerceFrontend->intercetta_login($username);
}
return $user;
}
add_filter( 'authenticate', 'intercetta_login', 30, 3 );
Basically during logout there is a $_GET variable set, if you exclude that variable properly you avoid entering the custom update functionality.
It's not awesome, but works.
What I learned: add_filter( 'authenticate'...) is called also during logout. Be aware of that, I took me a lot of time to figure that out.
If anyone has a better solution feel free to answer.
Filter 'authenticate' is called even when just visit URL with /wp-login.php.
So better check if $username and $password are not empty in the begin of the function.
if ($username == '' || $password == '') return $user;

Agiletoolkit Maximum number of failed login attempts

The agiletoolkit Auth/basic class allow to try to login without any limitation.
And i'm searching a way to limit the number of failed login attempt, i've tried to override some methods of this class but it use ajax reloading so php code is not executed correctly.
Any suggestion is welcome.
Many Thanks,
Inspired by StackOverflow I have implemented the following protection:
for each user we store soft / hard lock. Hard lock would refuse to verify password even if it's correct.
soft lock is a period of time after which we will reset "unsuccessful attempt" counter.
every time you type incorrect password both soft and hard lock increase making you wait longer (but not forever)
gradual increase puts a reasonable limit so if your attacker tries to hack your account for a hour - he will only get several attempts in, yet your account will be OK to log-in after few hours.
I have implemented this in one of my projects, although it's not a controller, but a built-in code. Please look through comments and I hope this will help you and others:
In User model add:
$this->addField('pwd_locked_until');
$this->addField('pwd_failure_count');
$this->addField('pwd_soft_unlock');
You'll also need two methods:
/* Must be called when user unsuccessfully tried to log-in */
function passwordIncorrect(){
$su=strtotime($this['pwd_soft_unlock']);
if($su && $su>time()){
// aw, they repeatedly typed password in, lets teach them power of two!
$this['pwd_failure_count']=$this['pwd_failure_count']+1;
if($this['pwd_failure_count']>3){
$this['pwd_locked_until']=date('Y-m-d H:i:s',time()
+pow(2,min($this['pwd_failure_count'],20)));
$this['pwd_soft_unlock']=date('Y-m-d H:i:s',time()
+max(2*pow(2,min($this['pwd_failure_count'],20)),60*5));
}
}else{
$this['pwd_failure_count']=1;
$this['pwd_soft_unlock']=date('Y-m-d H:i:s',time() +60*5);
}
$this->save();
}
and
/* Must be called when user logs in successfully */
function loginSuccessful(){
$this['last_seen']=date('Y-m-d H:i:s');
$this['pwd_soft_unlock']=null;
$this->save();
}
Finally - you can use this as a login form:
class Form_Login extends Form {
function init(){
parent::init();
$form=$this;
$form->setModel('User',array('email','password'));
$form->addSubmit('Login');
if($form->isSubmitted()){
$auth=$this->api->auth;
$l=$form->get('email');
$p=$form->get('password');
// check to see if user with such email exist
$u=$this->add('Model_User');
$u->tryLoadBy('email',$form->get('email'));
// user may have also typed his username
if(!$u->loaded()){
$u->tryLoadBy('user_name',$form->get('email'));
}
// incorrect email - but say that password is wrong
if(!$u->loaded())$form->getElement('password')
->displayFieldError('Incorrect Login');
// if login is locked, don't verify password at all
$su=strtotime($u['pwd_locked_until']);
if($su>time()){
$form->getElement('password')
->displayFieldError('Account is locked for '.
$this->add('Controller_Fancy')
->fancy_datetime($u['pwd_locked_until']));
}
// check account
if($auth->verifyCredentials($u['email'],$p)){
// resets incorrect login statistics
$u->loginSuccessful();
$auth->login($l);
// redirect user
$form->js()->univ()->location($this->api->url('/'))->execute();
}else{
// incorrect password, register failed attempt
$u->passwordIncorrect();
$form->getElement('password')->displayFieldError('Incorrect Login');
}
}
}
}
This should be converted into add-on by someone.
I think you may store numbers of usage of Model_User (usually used in Auth) in session or cookies using afterLoad hook and then check it where you need to.
Oops. FAILED login. So you model is NOT loaded.
You need just to count clicks on a button of a login form and store it somewhere (cookies, database). So create your own login form and add some condition when a form is submitted like:
$m = $this->add('Model_User');
$f = $this->add("Form");
$f->setModel($m, array('email', 'password'));
$f->addSubmit("Log In");
if ($f->isSubmitted()){
//Limmiting
if($_COOKIE[$this->api->name."_count_failed_login"] >= 5/*Here's you limit number*/){
/*redirect or something else*/
}
if (/*here should be you condition*/){
$_COOKIE[$this->api->name."_count_failed_login"] = 0;
$this->api->auth->login($f->get("email"));
$f->js()->univ()->redirect("index")->execute();
}else{
/* when login is failed*/
if($_COOKIE[$this->api->name."_count_failed_login"]){
$_COOKIE[$this->api->name."_count_failed_login"]++;
}else{
$_COOKIE[$this->api->name."_count_failed_login"] = 1;
}
$this->js()->univ()->alert('Wrong username or password')->execute();
}
}
I didn't check it. Maybe some adjastements are needed.
Just an idea.
Hope that helps.

create an action based on specific database information

UPDATE: Not sure why the answer was removed. But i did receive a solution and for future views I am leaving the original code below. But to make this work we simply needed to change:
if (site_active == 0)
TO:
if ($row['site_active'] == 0)
We also removed the "else exit;" code so if the site was active the page would continue to load like normal. Thank you to whoever posted this answer. Not sure why you deleted it because it worked.
Original Question:
Ok, I am using MYSQL as a database and then php for my script. I am wanting to make a script that checks whether a user's site is "active" or "disabled" this code will be placed at the beginning of each webpage. If the users website is "active" then the website will continue to load normally. If the users website is "disabled" then the website will redirect to an error page that states so.
If my client does not pay the monthly hosting fee then I will set the site to "disabled" in the database and the site will not be accessible until the payment is made. which then I will return it to an "active" state and it will be accessible again. I have came up with the following code so far (I am new to php so if it's stupid don't judge please!) When this code is executed it redirects to the page I have set no matter what rather than displaying the regular site. Any help or suggestions to make this work would be greatly appreciated!
<?php
$con=mysqli_connect("CONNECTION INFO REMOVED FOR SECURITY REASONS");
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$result = mysqli_query($con,"SELECT * FROM mypanda_clients
WHERE id='34'");
while($row = mysqli_fetch_array($result))
{
if (site_active == 0)
{
header('Location: http://www.green-panda.com/');
}
else
{
exit;
}
}
?>
<html>
<h2>Congratulations, your site is active!</h2>
</html>
Give this a try,
if ($row['site_active'] == 0)
{
.....
}

Categories