My goal is to destroy the logged-in used session and force him to log in again if he was idle for 20 minutes. Here is my way of doing it:
In each controller, I do this check:
if(reach_idle_limit()) {
redirect('logout');
}
And reach_idle_limit() is a helper method in one of my helper classes:
function reach_idle_limit() {
$idle_period = 1200; //20 mins
$CI =& get_instance();
$last_activity = $CI->session->userdata('last_activity');
$now_time = time();
//If $last_activity is not set, don't force a logout
if($last_activity == False || $last_activity == 0){
return false;
}
//If idle period exceeded: destroy the session and return true
else if($now_time - $last_activity > $idle_period){
$CI->session->sess_destroy();
return true;
}
//else, update session's last_activity to current time, return false
else{
$CI->session->set_userdata('last_activity', $now_time);
return false;
}
}
This works fine when I give $idle_period a small value, like 60 sec. But when I give it the value I seek, 20 min, it doesn't work!
FYI:
I'm using ag_auth library with Codeigniter (for the authentication part).
My config's variable sess_expiration is set to 0.
In this case, why not use session.gc_maxlifetime?
session.gc_maxlifetime specifies the number of seconds after which data will be seen as 'garbage' and potentially cleaned up. Garbage collection may occur during session start (depending on session.gc_probability and session.gc_divisor).
just use:
ini_set('session.gc_maxlifetime',20);
Related
In laravel 7, I setup cronjobs that runs base from different users specific timezone.
Here's the exact code:
foreach (User::role('admin')->get() as $user) {
/* with queue job */
$schedule->command('weekly-survey:send')->timezone($user->timezone)->weekly()->wednesdays()->at('8:00');
$schedule->command('update:surveys-completed')->timezone($user->timezone)->daily();
$schedule->command('trial:reminder')->timezone($user->timezone)->dailyAt('7:45');
$schedule->command('trial:ends')->timezone($user->timezone)->dailyAt('23:00');
$schedule->command('subscribe:customer')->timezone($user->timezone)->dailyAt('23:45');
$schedule->command('update:user-invoice')->timezone($user->timezone)->everyMinute();
$schedule->command('employees:update-status')->timezone($user->timezone)->everyMinute();
$schedule->command('subscription:update-quantity')->timezone($user->timezone)->daily();
$schedule->command('update:freeze-account')->timezone($user->timezone)->dailyAt('22:45');
$schedule->command('send:upcoming-survey-notification')->timezone($user->timezone)->weeklyOn(1, '8:00');
$schedule->command('surveys:end-soon')->timezone($user->timezone)->dailyAt('8:00');
/* end with queue job */
/* without queue */
$schedule->command('amazon:get-send-qouta')->timezone($user->timezone)->dailyAt('23:55');
$schedule->command('amazon:get-statistics')->timezone($user->timezone)->dailyAt('23:55');
$schedule->command('update:customer-success-table')->timezone($user->timezone)->everyMinute();
$schedule->command('csm:prev-month-active')->timezone($user->timezone)->lastDayOfMonth('23:59');
$schedule->command('update:monthly-earning')->timezone($user->timezone)->lastDayOfMonth('23:59');
$schedule->command('update:subscription-status')->timezone($user->timezone)->everyMinute();
$schedule->command('retrieve:past-due-subscription')->timezone($user->timezone)->dailyAt('23:59');
$user = new User();
$user->accountNotificationsSchedule($schedule);
$schedule->command('horizon:snapshot')->timezone($user->timezone)->everyFiveMinutes();
/* end without queue */
\Log::info("Cron entry successfully executed!");
}
Do this code safe to run? First I loop through all users where has admin role and then pass user time zone to each of the command. I'm sure that this code will infinitely run for as long as the server is alive. I just want to have an alternative safe approach.
Here's what I implemented and it works.
public function handle(TimezoneRepository $timezoneRepository)
{
// get user's unique timezone
$timezones = $timezoneRepository->getUniqueTimezones();
foreach ($timezones as $timezone) {
$date = Carbon::now($timezone);
// send only on Wednesday at 8:00 am
if ($date->isWednesday() && $date->hour == 8 && $date->minute == 0) {
Survey::SendSurvey();
}
}
}
I used put function for make new manual Cashe. for example :
$cashtime =Cache::put('filekey', 'mycashtime', 20);
and sent it to view but it not expired .
when i send it to view it will back me true. but after 20s have to send me false and expire it.
and then how can i check it is expired or not .
I solved it.my problem was first I have to check if key doesnt exist set again else do someting.
view()->composer('admin.sidebar', function($view){
$cashtime = Cache::get('filekeys');
if($cashtime == Null){
Cache::put('filekeys', 'mycashtimes', now()->addMinutes(1));
//do something
}else{
//do something
}
$view->with(['testmneda' => $cashtime]);
});
I have configured a listener on kernel.request which sets a new response with redirect when the session time has reached a certain value. The listener works fine and redirects to a certain page, on the next request, after the session has ended. But my problem is on the page I have many links and if I press multiple times the same link, the initial request with the redirect is cancelled/stopped and a new request is made with the last link pressed and so it passes my redirect even though the session has ended and is destroyed. So, my question is how to prevent additional requests/link presses after the firs request is made?
Here is my code:
public function onKernelRequestSession(GetResponseEvent $event)
{
$request = $event->getRequest();
$route = $request->get('_route');
$session = $request->getSession();
if ((false === strpos($route, '_wdt')) && ($route != null)) {
$session->start();
$time = time() - $session->getMetadataBag()->getCreated();
if ($route != 'main_route_for_idle_page') {
if (!$session->get("active") && $route == 'main_route_for_site_pages') {
$session->invalidate();
$session->set("active", "1");
} else {
if ($time >= $this->sessionTime) {
$session->clear();
$session->invalidate();
$event->setResponse(new RedirectResponse($this->router->generate('main_route_for_idle_page')));
}
}
} else {
if ($session->get("activ")) {
$session->clear();
$session->invalidate();
}
}
}
}
Thak you.
Idea #1: Simple incremental counter
Each request sends sequence number as param which is being verified as expected at the server.
Server increments the number and sends it back via response
the new number is used in future requests
Basically, if server expects the SEQUENCE number to be 2 and client sends 1 the request is to be rejected.
Idea #2: Unique hash each time
Similar to the idea above, but uses unique hashes to eliminate predictive nature of incremental sequence.
I resolved the issue using JQuery: when a link was pressed I disabled the other ones and so only one request is made from the page:
var isClicked = false;
$(".menu-link").click(function(e) {
if(!isClicked) {
isClicked = true;
} else {
e.preventDefault();
}
});
Thanks.
Garbage collection function in CI
function _sess_gc()
{
if ($this->sess_use_database != TRUE)
{
return;
}
srand(time());
if ((rand() % 100) < $this->gc_probability)
{
$expire = $this->now - $this->sess_expiration;
$this->CI->db->where("last_activity < {$expire}");
$this->CI->db->delete($this- ;
log_message('debug', 'Session garbage collection performed.');
}
}
Im new in codeigniter and i have found this GC function in codeigniter which in the Session.php libraries folder.
My problem is
how to change the time for the GC to delete expired session?
Example: I want it to delete expired session every 3mins..
But this function will delete expired session from database if the probability percentage is met..
Is there's a way of doing it?
right now I'm using an antiflood function in all my websites :
function flood($name,$time)
{
$name = 'tmptmptmp'.$name;
if(!isset($_SESSION[$name]))
{
$_SESSION[$name] = time();
return true;
}
else
{
if(time()-$time > $_SESSION[$name])
{
$_SESSION[$name] = time();
return true;
}
else
{
return false;
}
}
}
I use it this way :
if(flood('post',60)) do something;
else 'you're posting too fast';
Is this way safe ? Or do I need to replace it/complete it with a db table stocking ips and checking if they did a request earlier ?
It depends. How likely are your users going to clear their cookies to get past your anti-flood protection? I'll say that if they have to login again, 99% of the users won't even bother.
But sure, if you really want better method, store the ips in the DB. But even that can be defeated by getting a new IP.