I've visited my website for the first time and I see the session cookie set by server. I'm reloading the page and I see that only my browser sends the session identifier to server, while server doesn't return session cookie. I'm using Kohana framework. I'm wondering whether this is native PHP behavior to not send session cookie if the request already has it and it's not expired or this is handled by the framework?
I've found the following piece of code which presumable does the magic:
protected function _read($id = NULL)
{
// Sync up the session cookie with Cookie parameters
session_set_cookie_params($this->_lifetime, Cookie::$path, Cookie::$domain, Cookie::$secure, Cookie::$httponly);
// Do not allow PHP to send Cache-Control headers
session_cache_limiter(FALSE);
// Set the session cookie name
session_name($this->_name);
if ($id)
{
// Set the session id
session_id($id);
}
// Start the session
session_start();
// Use the $_SESSION global for storing data
$this->_data =& $_SESSION;
return NULL;
}
Is it what I'm looking for?
Official manual says:
When session_start() is called or when a session auto starts, PHP will
call the open and read session save handlers. These will either be a
built-in save handler provided by default or by PHP extensions (such
as SQLite or Memcached); or can be custom handler as defined by
session_set_save_handler().
The read callback will retrieve any existing session data (stored in a
special serialized format) and will be unserialized and used to
automatically populate the $_SESSION superglobal when the read
callback returns the saved session data back to PHP session handling.
So the answer should sound like this: This is native PHP behavior unless you defined custom save handler by session_set_save_handler().
Related
I have an app integrated with saml2 on azure, on my system I always check to see if the user is logged in using:
$as = new \SimpleSAML\Auth\Simple('default-sp');
$as->requireAuth();
however when I log out the user from azure the requireAuth returns that the user is still logged in, only when I close the browser and enter it again it sends the user to log in again.
Using PHP sessions in SimpleSAMLphp will close any existing session when invoked for the first time, and its own session will prevail afterwards.
If you want to restore your own session after calling SimpleSAMLphp, you can cleaning up the session by using following steps:
$session = \SimpleSAML\Session::getSessionFromRequest();
$session->cleanup();
If you don't want to cleanup SimpleSAMLphp's session and try to use $_SESSION afterwards, you won't be using your own session and all your data is likely to get lost or inaccessible.
Note that if your application uses a custom session handler. You can lead to problems because SimpleSAMLphp's stand-alone web UI uses the default PHP session handlers. So, you need to unset the custom handler before making any calls to SimpleSAMLphp:
// use custom save handler
session_set_save_handler($handler);
session_start();
// close session and restore default handler
session_write_close();
session_set_save_handler(new SessionHandler(), true);
// use SimpleSAML\Session
$session = \SimpleSAML\Session::getSessionFromRequest();
$session->cleanup();
session_write_close();
// back to custom save handler
session_set_save_handler($handler);
session_start();
Refer Doc & SO thread for usage of session
I have a PHP script that uses session_decode to get the session variables of customer's session (from session stored file).
The problem is that whenever I call the script and it reads the session variables, it also add them to my own session. Is there a way to avoid this or maybe use a better method to get the customer's session information without using session_decode?
Thanks
I think I have found the simplest solution/workaround:
<?php
// if session is not started
session_start();
// store our current session
$my_sess = $_SESSION;
// decode $data (the encoded session data, either from a file or database). Remember, decoded data is put directly into $_SESSION
session_decode($data);
$data = $_SESSION;
print_r($data);
// restore our own session
$_SESSION = $my_sess;
?>
I am having problems with a custom start session.For security reasons I decide to look for a method that is safe when starting a session and I came across this tutorial and implemented the method related to start session.
The problem is that whenever I am initiating a new session variable and redirect to another page which is expecting the value from the initialized session, all my session variable that I initialed earlier on get destroyed forcing the user to logout.Below is my function I am using to start sessions:
function sec_session_start(){
$session_name = 'sec_session_id';//set a custom session Name
$secure = false;//true if are using https
$httponly = true; //this stops javascript from accessing session id
ini_set('session.use_only_cookies', 1);//FORCES session to only use cookies
$cookie_params = session_get_cookie_params();//Get current cookie params
session_set_cookie_params($cookie_params['lifetime'],$cookie_params['path'],$cookie_params['domain']
,$secure,$httponly);
session_name($session_name);//set the session name to the one set above
if (!isset($_SESSION)){session_start();}//start the php session
session_regenerate_id();//regenerate new session id and delete the old one THIS IS TO PREVENT SESSION HIJACK
}
I have searched for an answer to my problem with no luck, Please help me on this.
N.B - when I use the default session_start
everything works perfect.
You should start session, not when $_SESSION is not set.
if (!isset($_SESSION)){session_start();}//start the php session
session_regenerate_id();//regenerate new session id and delete the old one THIS IS TO PREVENT SESSION HIJACK
should be
session_start();//Start new or resume existing session
session_regenerate_id();//regenerate new session id and delete the old one THIS IS TO PREVENT SESSION HIJACK
Reference: session_regenerate_id
Try to put session_start() at top of your php code, as first instruction.
I want to implement a PHP custom session ID, while avoiding calling session_start() more than necessary.
Basically, one simple algorithm is
session_start();
if ( ! isset( $_SESSION['MyStuff'] )) {
session_write_close();
session_id( generate_my_id() );
session_start();
}
$_SESSION['MyStuff'] = some stuff...;
In case the session expired or didn't exist in the first place, the first session_start() will create its own ID and send a cookie to the browser. Then the session is ended, and another one is created, with another cookie sending (plus the overhead of creating and closing a session file).
Another solution would be to test if a PHPSESSID cookie exists, and its value having the format according to the - home cooked - generate_my_id() function - then test again if the $_SESSION value. But if the session expired (no $_SESSION['MyStuff']), again, a non-necessary session_start() will have been called.
So the question is, based on my observations, actually two questions
is there a way to specify how PHP should create the session ID (doesn't seem to be possible), before calling session_start()?
is there a way to check if session_start() will have to create a new session, or will just use the one available server side? (that would eliminate its first call)
Any good alternative is welcome.
Edit
Clarification about what is a custom id.
The session ID is the string key used by PHP to retrieve a session on the server, each user having a different key. That key is usually stored in a cookie, then the browser sends that cookie with its requests to the server / PHP to "connect" to the session.
PHP sets the session ID key automatically, based on MD5(user-and-time-related-data) or SHA1(same-related-data), based on settings. Thus, the session ID is either a MD5 or a SHA1 key - hopefully unique.
A custom ID is a key created manually by the programmer (me), bypassing the md5/sha1 creation.
Yes, from 5.3 onwards you can specify the hash algorithm with session.hash_function when a session id gets generated; using your own hash algorithm is not recommended, especially since the ones that come with hash are extensively tested for spread, speed, collisions, etc.
Since cookies are typically used to perpetuate sessions, you can use that information to determine whether session_start() will create a new session or not.
The following illustrates a way to minimize the number of session_start() statements you need; it's deduced from existing code (which is OO):
do {
// discover session by cookie
if (isset($_COOKIE[session_name()])) {
session_start();
// validate session contents
if (!isset($_SESSION['MyStuff'])) {
// destroy session and regenerate id
session_destroy();
session_regenerate_id(true); // skip this if you generate your own
} else {
// validation passed, no need to populate
break;
}
}
// populate new session
// you can use session_id($your_id) here
session_start();
$_SESSION['MyStuff'] = 'foobar';
} while (false);
The strange do { } while loop is just a glorified goto so that you can skip the second session_start() if the current session is valid.
Late answer but check the changelog for PHP v5.5.1
It refers a new interface called SessionIdInterface which only method is create_sid, although it's still undocumented.
interface SessionIdInterface {
public function create_sid ();
}
I'm developing a site using Wordpress.
My permalink structure is set to show post/page name. So accessing a page called store will look like this: www.mysite.com/store/?some=arguments
In all my WP templates, I'm able to output all my SESSION variables using print_r($_SESSION);
Doing the same from a file called from jQuery.ajax only outputs some of the SESSION varaibles.
I've used the following code to see if the cookie path is same for both files, and they are:
$sessCookie = ini_get('session.cookie_path');
echo 'session.cookie_path: '.$sessCookie;
I also have this code in my files to make sure session is started:
if (!session_id())
session_start();
Why am I not able to output the same session variables from a WP template and a php file called from jQuery.ajax?
UPDATE
jQuery.ajax calls jquery.php file. At the top of this file, it has the following code:
require_once($_SERVER['DOCUMENT_ROOT'].'/wp-blog-header.php');
This code fires functions.php. In this file I have the following code:
function session_manager() {
if (!session_id())
session_start();
// Get variables in query string
$_SESSION['action'] = (isset($_GET['action']) ? $_GET['action'] : '');
$user_geo_data = get_geoip_record();
$_SESSION['user_geo_location'] = get_object_vars($user_geo_data);
}
When functions.php is fired from jquery.php, it seems that session_id() returns false, thus I create a new session.
Is there a way to keep using the same session?
UPDATE 2
It seems that WP config kills all GLOBAL variables when initialized.
http://wordpress.org/support/topic/wp-blog-headerphp-killing-sessions
Wordpress can use its own session handler, and overrides the default session handler to do so. So in essence you've got two different sessions, even though they share the same ID. The cookie path is merely how the client-side cookie operates. What you need to check is session_save_path(), and check if WP is running sessions through the database instead of the default file handler.
The reason two sessions are fired up is because the first one is browser-based (through a cookie) and the second one, with Ajax, is essentially server-side and doesn't have access to the session cookie.
The session cookie is where the session ID is stored and is used to identify an existing session. A server-side Ajax script doesn't have access to the browser's cookies, thus fires up a new session.
It can be worse if the main script uses an alternate session "save handler" than the Ajax script, resulting in two separate sessions, stored in two different places.