i am using codeigniter
with ion_auth configured ,and MySQL as back-end,
my app run smoothly but sometime/not randomly when i call add/update functions it automatically log me out.
i am working on it for last 1 months but found no solution so far ?
i also change setting in ion_auth config file.
$config['user_expire'] = 0;
any idea ,solution to this problem?
please comment ,so that i can provide more data if needed.
Note: i have also check this but no luck.
You are probably performing ajax requests, this is a common issue...
I would suggest you to use session database and make ajax calls is to not update the session...
Make this on you session class
class MY_Session extends CI_Session {
public function sess_update()
{
$CI =& get_instance();
if ( ! $CI->input->is_ajax_request())
{
parent::sess_update();
}
}
}
Create a session library with your own MY_Session.php library that overwrote the sess_update method with one that only executed the update method when not an AJAX request:
MY_Session.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
require_once BASEPATH . '/libraries/Session.php';
class MY_Session extends CI_Session
{
function __construct()
{
parent::__construct();
$this->CI->session = $this;
}
function sess_update()
{
// Do NOT update an existing session on AJAX calls.
if (!$this->CI->input->is_ajax_request())
return parent::sess_update();
}
}
Location of file:
/application/libraries/MY_Session.php */
You can either auto-load this library from config/autoload.php:
$autoload['libraries'] = array( 'MY_Session');
Or, you can load it later:
$this->load->library('MY_Session');
What this sess_update(); does?
In your system/libraries/Session.php there is a function sess_update() that automatically update your last activity.This function update the session every five minutes by default.
public function sess_update()
{
// We only update the session every five minutes by default
if (($this->userdata['last_activity'] + $this->sess_time_to_update) >= $this->now)
{
return;
}
// _set_cookie() will handle this for us if we aren't using database sessions
// by pushing all userdata to the cookie.
$cookie_data = NULL;
/* Changing the session ID during an AJAX call causes problems,
* so we'll only update our last_activity
*/
if ($this->CI->input->is_ajax_request())
{
$this->userdata['last_activity'] = $this->now;
// Update the session ID and last_activity field in the DB if needed
if ($this->sess_use_database === TRUE)
{
// set cookie explicitly to only have our session data
$cookie_data = array();
foreach (array('session_id','ip_address','user_agent','last_activity') as $val)
{
$cookie_data[$val] = $this->userdata[$val];
}
$this->CI->db->query($this->CI->db->update_string($this->sess_table_name,
array('last_activity' => $this->userdata['last_activity']),
array('session_id' => $this->userdata['session_id'])));
}
return $this->_set_cookie($cookie_data);
}
// Save the old session id so we know which record to
// update in the database if we need it
$old_sessid = $this->userdata['session_id'];
$new_sessid = '';
do
{
$new_sessid .= mt_rand(0, mt_getrandmax());
}
while (strlen($new_sessid) < 32);
// To make the session ID even more secure we'll combine it with the user's IP
$new_sessid .= $this->CI->input->ip_address();
// Turn it into a hash and update the session data array
$this->userdata['session_id'] = $new_sessid = md5(uniqid($new_sessid, TRUE));
$this->userdata['last_activity'] = $this->now;
// Update the session ID and last_activity field in the DB if needed
if ($this->sess_use_database === TRUE)
{
// set cookie explicitly to only have our session data
$cookie_data = array();
foreach (array('session_id','ip_address','user_agent','last_activity') as $val)
{
$cookie_data[$val] = $this->userdata[$val];
}
$this->CI->db->query($this->CI->db->update_string($this->sess_table_name, array('last_activity' => $this->now, 'session_id' => $new_sessid), array('session_id' => $old_sessid)));
}
// Write the cookie
$this->_set_cookie($cookie_data);
}
Replace line 346 in system/libraries/Session.php (function sess_update())
if (($this->userdata['last_activity'] + $this->sess_time_to_update) >= $this->now)
With:
if (($this->userdata['last_activity'] + $this->sess_time_to_update) >= $this->now || $this->CI->input->is_ajax_request())
hope this works for you .
this is best answer.
codeignter controller
function fetchSendToProduction($sku,$old_fab_id)
{
if($this->input->is_ajax_request() > 0)
{
$result = $this->ifmodel->fetchSendToProduction($sku,$old_fab_id);
echo json_encode($result);
}
}
codeignter view ajax call
$.ajax({
type: "POST",
url: "<?php echo base_url(); ?>index.php/inputFactor/fetchSendToProduction/" + sku+'/'+old_fab_id ,
cache: false,
processData: false,
success: function(data)
{
}
});
Related
I am facing problems with session data. After login to the website, I'm losing session data. I have tired creating sessions in database and also tried native php session class but nothing worked. I have also cleared tmp folder from server.
The website uses code igniter framework and it is hosted on godaddy VPS
Please help me. Thank You...
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
class CI_Session {
var $session_id_ttl; // session id time to live (TTL) in seconds
var $flash_key = 'flash'; // prefix for "flash" variables (eg. flash:new:message)
function CI_Session()
{
$this->object =& get_instance();
log_message('debug', "Native_session Class Initialized");
$this->_sess_run();
}
/**
* Regenerates session id
*/
function regenerate_id()
{
// copy old session data, including its id
$old_session_id = session_id();
$old_session_data = $_SESSION;
// regenerate session id and store it
session_regenerate_id();
$new_session_id = session_id();
// switch to the old session and destroy its storage
session_id($old_session_id);
session_destroy();
// switch back to the new session id and send the cookie
session_id($new_session_id);
session_start();
// restore the old session data into the new session
$_SESSION = $old_session_data;
// update the session creation time
$_SESSION['regenerated'] = time();
// session_write_close() patch based on this thread
// http://www.codeigniter.com/forums/viewthread/1624/
// there is a question mark ?? as to side affects
// end the current session and store session data.
session_write_close();
}
/**
* Destroys the session and erases session storage
*/
function destroy()
{
//unset($_SESSION);
session_unset();
if ( isset( $_COOKIE[session_name()] ) )
{
setcookie(session_name(), '', time()-42000, '/');
}
session_destroy();
}
/**
* Reads given session attribute value
*/
function userdata($item)
{
if($item == 'session_id'){ //added for backward-compatibility
return session_id();
}else{
return ( ! isset($_SESSION[$item])) ? false : $_SESSION[$item];
}
}
/**
* Sets session attributes to the given values
*/
function set_userdata($newdata = array(), $newval = '')
{
if (is_string($newdata))
{
$newdata = array($newdata => $newval);
}
if (count($newdata) > 0)
{
foreach ($newdata as $key => $val)
{
$_SESSION[$key] = $val;
}
}
}
/**
* Erases given session attributes
*/
function unset_userdata($newdata = array())
{
if (is_string($newdata))
{
$newdata = array($newdata => '');
}
if (count($newdata) > 0)
{
foreach ($newdata as $key => $val)
{
unset($_SESSION[$key]);
}
}
}
/**
* Starts up the session system for current request
*/
function _sess_run()
{
$session_id_ttl = $this->object->config->item('sess_expiration');
if (is_numeric($session_id_ttl))
{
if ($session_id_ttl > 0)
{
$this->session_id_ttl = $this->object->config->item('sess_expiration');
}
else
{
$this->session_id_ttl = (60*60*24*365*2);
}
}
session_start();
// check if session id needs regeneration
if ( $this->_session_id_expired() )
{
// regenerate session id (session data stays the
// same, but old session storage is destroyed)
$this->regenerate_id();
}
// delete old flashdata (from last request)
//$this->_flashdata_sweep();
// mark all new flashdata as old (data will be deleted before next request)
//$this->_flashdata_mark();
}
/**
* Checks if session has expired
*/
function _session_id_expired()
{
if ( !isset( $_SESSION['regenerated'] ) )
{
$_SESSION['regenerated'] = time();
return false;
}
$expiry_time = time() - $this->session_id_ttl;
if ( $_SESSION['regenerated'] <= $expiry_time )
{
return true;
}
return false;
}
/**
* Sets "flash" data which will be available only in next request (then it will
* be deleted from session). You can use it to implement "Save succeeded" messages
* after redirect.
*/
function set_flashdata($key, $value)
{
$flash_key = $this->flash_key.':new:'.$key;
$this->set_userdata($flash_key, $value);
}
/**
* Keeps existing "flash" data available to next request.
*/
function keep_flashdata($key)
{
$old_flash_key = $this->flash_key.':old:'.$key;
$value = $this->userdata($old_flash_key);
$new_flash_key = $this->flash_key.':new:'.$key;
$this->set_userdata($new_flash_key, $value);
}
/**
* Returns "flash" data for the given key.
*/
function flashdata($key)
{
$flash_key = $this->flash_key.':old:'.$key;
return $this->userdata($flash_key);
}
/**
* PRIVATE: Internal method - marks "flash" session attributes as 'old'
*/
function _flashdata_mark()
{
foreach ($_SESSION as $name => $value)
{
$parts = explode(':new:', $name);
if (is_array($parts) && count($parts) == 2)
{
$new_name = $this->flash_key.':old:'.$parts[1];
$this->set_userdata($new_name, $value);
$this->unset_userdata($name);
}
}
}
/**
* PRIVATE: Internal method - removes "flash" session marked as 'old'
*/
function _flashdata_sweep()
{
foreach ($_SESSION as $name => $value)
{
$parts = explode(':old:', $name);
if (is_array($parts) && count($parts) == 2 && $parts[0] == $this->flash_key)
{
$this->unset_userdata($name);
}
}
}
}
Always prefer to create sessions based on the framework's format. Even I too had the same problem. At that time I was using codeigniter version 2.0, so I used the frameworks session definitions. But as far as I know $_SESSION global variable is supported in version 3
Adding Custom Session Data
$this->session->userdata('item');
$this->session->set_userdata($array);
Retrieving Session Data
$this->session->userdata('item');
Retrieving All Session Data
$this->session->all_userdata()
Removing Session Data
$this->session->unset_userdata('some_name');
Check this documentation, you could get a clear view
https://ellislab.com/codeigniter/user-guide/libraries/sessions.html
When there are any page redirections, keep "exit" after redirect code.
That is how I solved my problem (losing session data after page redirection). See the below example.
header("Location: example.php");
exit;
I am having some issues with sessions.
In the first function queue, I save the session entries I can print this out from this function, so I can see its being set correctly.
In the function remove, I try and save this entries session into a variable and I get the error that entries is an undefined index.
Does anyone have any ideas what I am doing wrong here?
function queue()
{
session_start();
$status = 'Awaiting Moderation';
$channel = '1';
// Find all entries in 'Gallery' channel with 'Awaiting Moderation' status
$this->EE->db->select('entry_id')
->from('exp_channel_titles')
->where('status', $status)
->where('channel_id', $channel);
$query = $this->EE->db->get();
$entries = $query->result_array();
$entries_count = count($entries);
// Set count
$_SESSION['entries_count'] = $entries_count;
// If entries found
if ($entries_count > 0)
{
// Flatten entry ids array
$entriesFlat = array();
array_walk_recursive($entries, function($a) use (&$entriesFlat) { $entriesFlat[] = $a; });
$entriesSerial = serialize($entriesFlat);
// Save in session
$_SESSION['entries'] = $entriesSerial;
}
}
function remove()
{
session_start();
// Get session data + save into variable
$entries = $_SESSION['entries'];
}
You can only have one session and it should be at the top of your file.
Since your using codeigniter why not use codeigniter session and then autoload library and then you can do code like below.
$this->session->set_userdata('entries_count', $entries_count);
To Get Data
$this->session->userdata('entries_count');
And
$this->session->set_userdata('entries', $entriesSerial);
To Get Data
$this->session->userdata('entries');
// Example
if ($this->session->userdata('entries') > 0)
{
User Guide
CI2 http://www.codeigniter.com/userguide2/libraries/sessions.html
CI3: http://www.codeigniter.com/user_guide/libraries/sessions.html
http://www.codeigniter.com/docs
1st of all, there's not need to declare 'session' again at 'remove()' function..
2ndly to set session contents you have to write :
$this->session->set_userdata('entries_count', $entries_count);
Instead of
$_SESSION['entries'] = $entriesSerial;
Save it in session
To get session contents you've to write:
$entries_count = $this->session->userdata('entries_count');
Get session data + save into variable
Then you can write the condition like:
if ($entries_count > 0) {
}
Similarly, you've to write
$this->session->set_userdata('entries', $entriesSerial);
To save in session instead of
$_SESSION['entries'] = $entriesSerial;
And
$entries = $this->session->userdata('entries');
To Get session data + save into variable
here is the model:
<?php
class Generalfeaturesmodel extends CI_Model
{
protected $websitename;
public function __construct()
{
parent::__construct();
$this->websitename = 'GameSwap';
}
// helper function that retrieves all the data from the specified table. Basically since this is in the swap account model
// only use it for swap account related tables, not membership related tables for instance.
public function getdetails($tablename)
{
$query = $this->db->get($tablename);
$allrows = array();
$i=0;
foreach($query->result_array() as $row)
{
$allrows[$i++]=$row;
}
return $allrows;
}
// returns all the games based on the query conditions.
// #conditions - an associative array containing the conditions for the query.
// returns an array with all the games based on the where clauses.
public function gettargetswaps($where)
{
$query = $this->db->get_where('swaps',$where);
$targetswaps = array();
$i = 0;
foreach($query->result_array() as $s)
{
$query = $this->db->get_where('games',array('id'=>$s['gameid']));
$details = $query->row_array();
$gamedetails = array('name'=>$details['name'],'consoleid'=>$details['consoleid'],'genreid'=>$details['genreid'],'imgurl'=>$details['imgurl']);
$targetswaps[$i] = array_merge($s,$gamedetails);
$i++;
}
return $targetswaps;
}
}
?>
basically heres is the error i get when i load the above model:
A PHP Error was encountered
Severity: Warning
Message: Cannot modify header information - headers already sent by (output started at /home/phpgod/public_html/johnnyarias/ci_website/application/models/generalfeaturesmodel.php:50)
Filename: libraries/Session.php
Line Number: 672
and here is the function in the Session.php file thats throwing/or has to do with the error:
function _set_cookie($cookie_data = NULL)
{
if (is_null($cookie_data))
{
$cookie_data = $this->userdata;
}
// Serialize the userdata for the cookie
$cookie_data = $this->_serialize($cookie_data);
if ($this->sess_encrypt_cookie == TRUE)
{
$cookie_data = $this->CI->encrypt->encode($cookie_data);
}
else
{
// if encryption is not used, we provide an md5 hash to prevent userside tampering
$cookie_data = $cookie_data.md5($cookie_data.$this->encryption_key);
}
$expire = ($this->sess_expire_on_close === TRUE) ? 0 : $this->sess_expiration + time();
// Set the cookie
setcookie(
$this->sess_cookie_name,
$cookie_data,
$expire,
$this->cookie_path,
$this->cookie_domain,
$this->cookie_secure
);
}
And line 50 in the Generalfeaturesmodel is the end of the file(right after the '?>' php tag)...I have no idea what could be going wrong here???
Also appears to be a tab space in front of your <?php and as Damien mentioned, it is safer to leave the closing ?> so there is no output in the event a newline is saved at the end of the file
I'm using Codeigniter's Native Session Class for storing users information, but i have a serious problem. It appears that the session times out when the user is inactive for about half an hour and logs him out.
My config file looks like this:
$config['sess_cookie_name'] = 'cisession';
$config['sess_expiration'] = 60*60*24*30*12*2;
$config['sess_expire_on_close'] = FALSE;
$config['sess_encrypt_cookie'] = FALSE;
$config['sess_use_database'] = FALSE;
$config['sess_table_name'] = 'ci_sessions';
$config['sess_match_ip'] = FALSE;
$config['sess_match_useragent'] = TRUE;
$config['sess_time_to_update'] = 7200;
The PHPSESSID in browser is not destroyed when the user is logged out and it expires in two years as I've set it in config file.
I don't know what are the common problems with native session class because everyone seems to be happy with it, so can somebody work it out what is the most likely thing that is causing this problem?
Edit: For those who aren't familiar with codeigniter's native session class here is link
http://codeigniter.com/wiki/Native_session
i use also codeigniter's native class. Maybe you not config it correctly. Here is code that i get from him. https://github.com/EllisLab/CodeIgniter/wiki
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class CI_Session {
var $session_id_ttl; // session id time to live (TTL) in seconds
var $flash_key = 'flash'; // prefix for "flash" variables (eg. flash:new:message)
function __construct()
{
log_message('debug', "Native_session Class Initialized");
$this->object =& get_instance();
$this->_sess_run();
}
/**
* Regenerates session id
*/
function regenerate_id()
{
// copy old session data, including its id
$old_session_id = session_id();
$old_session_data = $_SESSION;
// regenerate session id and store it
session_regenerate_id();
$new_session_id = session_id();
// switch to the old session and destroy its storage
session_id($old_session_id);
session_destroy();
// switch back to the new session id and send the cookie
session_id($new_session_id);
session_start();
// restore the old session data into the new session
$_SESSION = $old_session_data;
// update the session creation time
$_SESSION['regenerated'] = time();
// session_write_close() patch based on this thread
// http://www.codeigniter.com/forums/viewthread/1624/
// there is a question mark ?? as to side affects
// end the current session and store session data.
session_write_close();
}
/**
* Destroys the session and erases session storage
*/
function destroy()
{
unset($_SESSION);
if ( isset( $_COOKIE[session_name()] ) )
{
setcookie(session_name(), '', time()-42000, '/');
}
session_destroy();
}
/**
* Reads given session attribute value
*/
function userdata($item)
{
if($item == 'session_id'){ //added for backward-compatibility
return session_id();
}else{
return ( ! isset($_SESSION[$item])) ? false : $_SESSION[$item];
}
}
/**
* Sets session attributes to the given values
*/
function set_userdata($newdata = array(), $newval = '')
{
if (is_string($newdata))
{
$newdata = array($newdata => $newval);
}
if (count($newdata) > 0)
{
foreach ($newdata as $key => $val)
{
$_SESSION[$key] = $val;
}
}
}
/**
* Erases given session attributes
*/
function unset_userdata($newdata = array())
{
if (is_string($newdata))
{
$newdata = array($newdata => '');
}
if (count($newdata) > 0)
{
foreach ($newdata as $key => $val)
{
unset($_SESSION[$key]);
}
}
}
/**
* Starts up the session system for current request
*/
function _sess_run()
{
session_start();
$session_id_ttl = $this->object->config->item('sess_expiration');
if (is_numeric($session_id_ttl))
{
if ($session_id_ttl > 0)
{
$this->session_id_ttl = $this->object->config->item('sess_expiration');
}
else
{
$this->session_id_ttl = (60*60*24*365*2);
}
}
// check if session id needs regeneration
if ( $this->_session_id_expired() )
{
// regenerate session id (session data stays the
// same, but old session storage is destroyed)
$this->regenerate_id();
}
// delete old flashdata (from last request)
$this->_flashdata_sweep();
// mark all new flashdata as old (data will be deleted before next request)
$this->_flashdata_mark();
}
/**
* Checks if session has expired
*/
function _session_id_expired()
{
if ( !isset( $_SESSION['regenerated'] ) )
{
$_SESSION['regenerated'] = time();
return false;
}
$expiry_time = time() - $this->session_id_ttl;
if ( $_SESSION['regenerated'] <= $expiry_time )
{
return true;
}
return false;
}
/**
* Sets "flash" data which will be available only in next request (then it will
* be deleted from session). You can use it to implement "Save succeeded" messages
* after redirect.
*/
function set_flashdata($key, $value)
{
$flash_key = $this->flash_key.':new:'.$key;
$this->set_userdata($flash_key, $value);
}
/**
* Keeps existing "flash" data available to next request.
*/
function keep_flashdata($key)
{
$old_flash_key = $this->flash_key.':old:'.$key;
$value = $this->userdata($old_flash_key);
$new_flash_key = $this->flash_key.':new:'.$key;
$this->set_userdata($new_flash_key, $value);
}
/**
* Returns "flash" data for the given key.
*/
function flashdata($key)
{
$flash_key = $this->flash_key.':old:'.$key;
return $this->userdata($flash_key);
}
/**
* PRIVATE: Internal method - marks "flash" session attributes as 'old'
*/
function _flashdata_mark()
{
foreach ($_SESSION as $name => $value)
{
$parts = explode(':new:', $name);
if (is_array($parts) && count($parts) == 2)
{
$new_name = $this->flash_key.':old:'.$parts[1];
$this->set_userdata($new_name, $value);
$this->unset_userdata($name);
}
}
}
/**
* PRIVATE: Internal method - removes "flash" session marked as 'old'
*/
function _flashdata_sweep()
{
foreach ($_SESSION as $name => $value)
{
$parts = explode(':old:', $name);
if (is_array($parts) && count($parts) == 2 && $parts[0] == $this->flash_key)
{
$this->unset_userdata($name);
}
}
}
}
PHPs sessions expires after 1440 seconds (24 minutes).
http://php.net/manual/en/session.configuration.php
I do have an issue with Codeigniter Database Session.
To make it short, I don't want multiple login with the same credentials(login/password).
The first verification is made by username/passwod matches in the database.
Here is my code
function index()
{
// Load Model.
$this->load->model('membres_model');
// Check if the user is already logged
if($this->session->userdata('alias') || $this->session->userdata('logged'))
{
//Redirect if he is logged.
redirect('membres/');
}
// If the form has been sent.
if($this->input->post('submit'))
{
// Trim data
$this->form_validation->set_rules('alias','Nom d\'utilisateur','trim|required|xss_clean');
$this->form_validation->set_rules('motdepasse','Mot de passe','trim|required|xss_clean');
if($this->form_validation->run())
{
// check verification in the model
if($this->membres_model->verification_connexion($this->input->post('alias'),$this->input->post('motdepasse')))
{
// Set userdata variables
$data = array(
'alias' => $this->input->post('alias'),
'addr_ip' => $_SERVER['REMOTE_ADDR'],
'hote' => gethostbyaddr($_SERVER['REMOTE_ADDR']),
'logged' => true
);
/****************************************
I Want to verify if the membres is already logged if another one want to use the same login/password of the logged on. but I don't know how to verify in the ci_sessions
*****************************************/
// start session
$this->session->set_userdata($data);
// Redirection sur l'espace membre apres la creation de la session.
redirect('membres/');
}
else {
// if return false
$data['error'] = 'Mauvais identifiants';
$data['contenu'] = 'connexion/formulaire';
$this->load->view('includes/template',$data);
}
}
else {
$data['contenu'] = 'connexion/formulaire'; // La variable vue pour loader dans le template.
$this->load->view('includes/template',$data);
}
}
else {
$data['contenu'] = 'connexion/formulaire'; // La variable vue pour loader dans le template.
$this->load->view('includes/template',$data);
}
}
}
I know I do have to use session Unserialize. I can't get the array but I don't know how to compare the data with the logged user. Does anybody can help me ?
Just add another column (say "user_id") to the sessions table, so you can check it with a single and simple SQL query. unserialize() (you'll need it) is typically a very slow function and checking each row in the sessions table might become an issue.
But ... here's how CodeIgniter unserializes it's session data:
protected function _unserialize($data)
{
$data = #unserialize(strip_slashes($data));
if (is_array($data))
{
array_walk_recursive($data, array(&$this, '_unescape_slashes'));
return $data;
}
return (is_string($data)) ? str_replace('{{slash}}', '\\', $data) : $data;
}
... and here's one called by it:
protected function _unescape_slashes(&$val, $key)
{
if (is_string($val))
{
$val= str_replace('{{slash}}', '\\', $val);
}
}
You could've used those directly if they were not protected, but ... it's still probably better that you just extend the Session library instead of implementing it on your own.
You could try something like this:
$sessions = "SELECT * FROM ci_sessions"; // return as object
foreach($sessions as $sess)
{
foreach(unserialize($sess->user_data) as $k => $v)
{
if($k === 'alias' AND isset($v))
{
return true;
}
}
}
OR as an alternative you might want to use a cookie
public function _before_check($alias) // alias should have UNIQUE constraint
{
return ($this->input->cookie('my_cookie_'.$alias, TRUE)) ? TRUE : FALSE;
}
Inside your form validation, do your before check!
if($this->_before_check($alias))
{
//already logged In
}
else
{
//log them in AND set your cookie
}
Con: They can bypass this if they attempt login via new computer
Note: you might want to set your expire time to match your session time, ie: 2 hours ( 7200 ).