Ajax and PHP Sessions - php

I have a template based site that relies on persistent sessions throughout. Recently I needed to expand the session storage by defining the save handler for database storage. This works fine in the general scope of the classes within the framework however when any of the pages make an ajax request the session id get regenerated and if the form gets submitted the previous session is gone.
<?php
require_once('site-database.php');
require_once('site-config.php');
class FileSessionHandler
{
private $database;
private $life_time;
public function FileSessionHandler(){
$this->life_time = get_cfg_var("session.gc_maxlifetime");
$this->database = new database();
$this->database->newConnection(db_host,db_user_name,db_user_pass,db_user_database);
session_set_save_handler(
array(&$this,'open'),
array(&$this,'close'),
array(&$this,'read'),
array(&$this,'write'),
array(&$this,'destroy'),
array(&$this,'gc')
);
}

Please check whether you have started the session with session_start().

I altered a few variables within the php.ini file to see if something in there was causing an issue and now it works as well in the database as it did file based. Keeping the same ID.
session.cookie_secure was set to 1 in the .ini file and I changed that to 0.

Related

PHP 8 Session Problem with Object serialization

I am facing a very strange Session problem on PHP 8(even though it doesn't work with 7.4 also, but on 7.3 it works great).
What i do is i cerated a class where i set up the Export Object and store it on Session $_SESSION['AjaxExport'][sessionid]. Now i want to load this object stored by reference on the ifram which processes the export. When i session_start it fails to load the session at all.
AjaxExporter Class
private function ExportIntro(){
while (ob_end_clean());
// remove any old ajax exports
unset($_SESSION['AjaxExport']);
$rnd = rand(1, 99999);
$this->sessionid = uniqid($rnd, true);
$_SESSION['AjaxExport'][$this->sessionid] = &$this;
Above, loads the modal where the user gets a link to start the Export. by clicking on that link i load the Below function which loads the Object from Session and start exporting by auto-reloading to export in process like (10%-20%...)
class NG_ADMIN_AJAXEXPORTER_CONTROLLER extends NG_ADMIN_BASE {
public function Export()
{
$sessionid = '';
if (!empty($_REQUEST['exportsess']) && isset($_SESSION['AjaxExport'][$_REQUEST['exportsess']])) {
$sessionid = $_REQUEST['exportsess'];
}
else {
return;
}
$exporter = &$_SESSION['AjaxExport'][$sessionid];
$exporter->sessionid = $sessionid;
$exporter->HandleToDo($_REQUEST['action']);
}
}
When the process tries to start, i get no session at all.
session_start(): Failed to decode session object. Session has been destroyed in...
Also tried to implement Seriazable on both classes but that not seam to work either because, even though the object is stored, there are no values in its properties so it's useless (even though i used reference &).
As i mentioned above, this code works just fine in php 7.3, the problems started since 7.4 and php 8
So, finally figured this out.
As a friend told me that if a class has static properties serialization may not work and i was loading Twig v3 on parent class, so i destroyed all the properties that may contained the "template" property from Twig and it worked.
Generally, cleaned my object to only contain the necessary sub-objects that needed to complete my exports.

Mediawiki SessionProvider $_SESSION variable is empty

I'm trying to implement a SessionProvider auth plugin for a mediawiki install.
I'm trying to integrate with an existing auth system that uses $_SESSION to indicate that a user is logged in, however any method I try, the resulting $_SESSION variable that I get inside the class' provideSessionInfo function is empty.
Previously this was done with a onUserLoadFromSession hook (that contained the bulk of the logic code below), but the update appears to have broken actually looking at the existing $_SESSION:
public function provideSessionInfo(WebRequest $request)
{
// $_SESSION is hidden away per-request, but $request->getSession likes to call this function (yay infinite loops)
if (!isset($_SESSION['memberid'])) {
return null;
}
$memberid = $_SESSION['memberid'];
$mr_user = MyRadio_User::getInstance($memberid);
$user = User::newFromName($memberid);
$dbr = wfGetDB(DB_REPLICA);
$s = $dbr->selectRow('user', ['user_id'], ['user_name' => $memberid]);
if ($s === false) {
return null;
} else {
$user->mName = $memberid;
$user->mId = $user->idForName();
$user->loadFromDatabase();
$user->saveSettings();
}
if ($mr_user->hasAuth(AUTH_WIKIADMIN) && !in_array('sysop', $user->getGroups())) {
$user->addGroup('sysop');
}
$user->mTouched = wfTimestampnow();
return new SessionInfo(SessionInfo::MAX_PRIORITY, [
'provider' => $this,
'persisted' => true,
'userInfo' => UserInfo::newFromUser($user, true),
]);
}
If I hardcode $memberid, the function and the session provider works fine, but I just can't seem to find a way to transfer the session from one PHP "application" to another.
Adding debugging shows the PHPSESSID variable still set in the cookie, but for whatever reason it can't be pulled out into an actual session object. I've tried various session_start() style methods to no effect.
I feel like I'm missing something obvious, but the documentation for this stuff is just a basic wiki page and the raw generated doxygen.
Session handling is not a good way of cross-application communication. MediaWiki uses its own session handling, which means there is no connection between $_SESSION in MediaWiki and $_SESSION in your application at all. The first will be populated from MediaWiki's object cache (as configured by $wgSessionCacheType), the other from PHP session files or whatever.
If you really do not have a better way to pass data, you'll have to write a custom access class which can be called by your provider, which will save the current session handler, install a null session handler (which restores PHP's native session handling which will hopefully be interoperable with the other application), start the session, fetch the session data, restore the original session handler, and probably start the session again.

Laravel sessions not available in native PHP?

New to Laravel and having some problems with Sessions. Specifically, reading session data from a PHP file outside of Laravel.
For example, let's say I set the session variable like so: Session::put('isAuthorized', 'yes') - I can retrieve this just fine in the Laravel context with Session::get('isAuthorized') but the following PHP will not retrieve this session key -
<?php
session_start();
echo $_SESSION['isAuthorized'];
?>
returns
Notice: Undefined index: isAuthorized in C:\xampp\htdocs\session.php on line 3
I have tried setting the Laravel session driver to both the default cookie and file modes, same result.
You could also write a session adapter, so the $_SESSION variable will be an instance of it:
<?php
class SessionAdapter implements \ArrayAccess {
public function offsetExists($offset) {
return Session::has($offset);
}
public function offsetGet($offset) {
return Session::get($offset);
}
public function offsetSet($offset, $value) {
return Session::put($offset, $value);
}
public function offsetUnset($offset) {
return Session::forget($offset);
}
}
And then somewhere in your code:
<?php
$_SESSION = new SessionAdapter();
// or
$GLOBALS['_SESSION'] = new SessionAdapter();
This way native PHP session and Laravel session will be "the same".
Laravel uses storage drivers for its sessions, namely cookie, file, database, memory, memcached and redis (and APC in Laravel 4).
The web is a stateless environment. This means that each request to your application is considered unrelated to any previous request. However, sessions allow you to store arbitrary data for each visitor to your application. The session data for each visitor is stored on your web server, while a cookie containing a session ID is stored on the visitor's machine. This cookie allows your application to "remember" the session for that user and retrieve their session data on subsequent requests to your application.
http://laravel.com/docs/session/config
The default storage driver is Cookie, so try this:
print_r($_COOKIE);
Please note that this answer is specific to Laravel 3
Laravel doesn't use PHP sessions, so forget session_start(), $_SESSION, etc.
If you're running with file session driver, the session data is stored in a file in storage/sessions. You can obtain the name of the file by reading the Laravel session ID from the cookie. So the hacky way to solve your problem would be to write some code that obtains the session ID from the cookie and then looks for the file with that name in the storage/sessions folder, read that file in, json_decode() it and you can read the whole thing.
If you're running with cookie session driver, all of the session data is stored in the cookie, but it is encrypted, so you'd have to have a copy of the key (which should be in application/config/application.php) and then figure out what encryption method Laravel is using so you can decrypt it. Then you can read all the session variables.
To achieve what you're hoping to achieve - that is, figure out if the current person is authorized, it might be better to build an API into your app and secure it so that it can only be accessed by localhost. Not a great solution from a performance standpoint, but potentially more elegant because you're not hacking around with the internals of Laravel session management.
Session handling in Laravel is indeed different from native PHP session. To use native PHP session, set the value as below:
<?php
session_start();
$_SESSION['isAuthorized'] = 'yes';
echo $_SESSION['isAuthorized']; // output yes
?>

Any set backs if I initialize codeigniter session every time controller gets called?

I having issues with Codeigniter sessions dying on IE randomly, I search everywhere and tried everything, the bug just wouldnt dissappear, i tried the function to check if ajax and wont sess_update() not working either, so my question is, what is the setback if I initialize the CI session every controller call? I have both native and CI sessions, but It would take me a few more days to change everything to Native sessions. its a temp fix.
class Transactions extends Controller {
function Transactions()
{
session_start();
parent::Controller();
$this->load->model('Modelcontracts');
$this->load->model('Modelsignup');
$this->load->model('Modeltransactions');
$this->session->set_userdata('account_id',$_SESSION['account_id']);
$this->session->set_userdata('email',$_SESSION['email']);
$this->session->set_userdata('account_type',$_SESSION['account_type']);
$this->session->set_userdata('parent_account_id',$_SESSION['parent_account_id']);
$this->session->set_userdata('accountrole_id',$_SESSION['accountrole_id']);
$this->session->set_userdata('user_type_id',$_SESSION['user_type_id']);
}
function index()
{
I never experience any problems with CodeIgniters sessions. Have you created the MySQL table for ci_sessions?
The setback is basicly that it's an unlogical call. If that doesn't matter, then I can't see any setbacks with it.
You could ease up the code like this though:
$arr = array('account_id', 'email', 'account_type', 'parent_account_id', 'accountrole_id', 'user_type_id');
foreach($arr as $h)
if (isset($_SESSION[$h]))
$this->session->set_userdata($h, $_SESSION[$h]);
// else echo "Session [{$h}] doesn't exist!";
Or extend your session library to do a
foreach(array_keys($_SESSION) as $h)
$this->CI->session->set_userdata($h, $_SESSION[$h]);
When loaded.
I don't think you should be using session_start() if you're having CodeIgniter manage your sessions (which you are if you're using CodeIgniter's set_userdata() / get_userdata() functions).
It says right at the top of the CI user docs that CI doesn't use PHP's native session handling, so this may be causing you trouble. The session is started automatically by loading the session library, either automatically if you put it in the config file or explicitly with $this->load->library('session');.
http://codeigniter.com/user_guide/libraries/sessions.html
-Gus
Edit: I came across a CI forum post regarding IE/CI session issues. Apparently it's a well-known issue. http://codeigniter.com/forums/viewthread/211955/

Why can't I store a PHP class instance as a SESSION variable

I have a PHP script that is called in 2 ways from a Dojo Ajax xhrGet call.
The first time it is called with an "init" argument which causes the script to create an instance of the StateList class and read in a file of state names.
session_start();
#include('StateList.php');
require_once('phplog.php');
//start executing here
$comd=$_GET['nexturl'];
if($comd=="init") {
$st = new StateList("../data/statestxt.txt");
$_SESSION['statefile'] = $st;
}
The second and further times, another xhrGet call passes a "getstate" argument and the following code tries to get the instance ofr the StateList class from the SESSION array.
if($comd =="getstate") {
$st= $_SESSION['statefile'];
phplog("size=".$st->getSize());
}
However, the getSize() method is never executed, nor can I call any other method
on the reconstituted StateList class instance.
Note that this is one PHP script that DOES include the class definition at the top
and thus the class methods should be known and avaialble.
What am I missing here?
You need to include the class definition before you call session_start(), otherwise the object will not be deserialized correctly and will be an instance of __PHP_Incomplete_Class. Otherwise what you have should work fine.
You may need to serialize the $st object/variable before you store it. This will ensure that everything is saved to the session. This is definitely the way to go for object oriented code. When you want to use the data again, you must unserialize it.
This is one of those things that's hard to debug in isolation. Storing instantiated objects in PHP Sessions is always a little tricky, and not 100% guaranteed to work. Here's some general debugging tips that may help you figure this out.
First, check your apache error log. Are you getting a "method called on non-object error"? If so, this means you're not getting an object back out of the session. If not, is there an error that indicated your method call is failing for another reason?
Second, check to see what you're really getting out of your session.
if($comd =="getstate") {
$st= $_SESSION['statefile'];
//get the class of st
phplog("instance=".get_class($st));
//get a reflection dump of st
$ref = new ReflectionClass($st);
$string = $ref->__toString();
phplog("reflection=".$string);
}
Third, look at the serialized string value that is being stored in the session itself. Are you actually storing a serialized object? In your dev environment, set the session.save_path ini value in php.ini to something like /tmp, (or use the ini_set method to do the same thing):
session.save_path = "/tmp"
and then examine the files created in /tmp (or whatever folder). You should see a string that starts with:
statefile:O:..........
The name of the class that instantiated the object will also be included in there, as well as values saved to properties.
If you are going to store an object in the session it must be link text.There are a LOT of problems with serializing objects in PHP, let alone storing them in the session. I recommend against doing this altogether, and finding a different solution for your problem. If you are going to do it though, you should look into the 'magic methods' link text which you should define in your class to facilitate it's reinstantiation when it is called from the session.
Do you have session.auto_start enabled? The manual's session page states that if you do, you have to load the class definition differently:
If you turn on session.auto_start then the only way to put objects into your sessions is to load its class definition using auto_prepend_file in which you load the class definition else you will have to serialize your object and unserialize it afterwards.
http://php.net/manual/en/intro.session.php
As that page says, the serialization/unserialization of the object will normally be done automatically by PHP, but having session.auto_start enabled will change this.
Try this:
include('StateList.php');
require_once('phplog.php');
// start your session after including your class file
session_start();
//start executing here
$comd=$_GET['nexturl'];
if($comd=="init") {
$st = new StateList("../data/statestxt.txt");
$_SESSION['statefile'] = $st;
}
if($comd =="getstate") {
// the ampersand creates a reference, preserving any further changes to your session data
$st = &$_SESSION['statefile'];
phplog("size=".$st->getSize());
}

Categories