Session loses variable stored after parent.location.reload() called in PHP - php

Below is the main code that goes to the session and constructor after it stores data in the session.
if(!$result->uid) {
$this->member_model->scripts("Wrong ID or PWD.");
} else {
$userdata['uid'] = $result->uid;
$this->session->set_userdata($userdata);
//header('location: /adminBase.php');
echo "<script>";
echo "parent.location.reload();";
echo "</script>";
exit();
}
On the login part, it stores UID through $this->session->set_userdata($userdata);,
Here is the part where it stores
public function set_userdata($data, $value = NULL)
{
if (is_array($data))
{
foreach ($data as $key => &$value)
{
$_SESSION[$key] = $value;
}
return;
}
$_SESSION[$data] = $value;
}
but when it goes to the constructor through
echo "<script>";
echo "parent.location.reload();";
echo "</script>";
it removes previous session that keeps UID.
if ($class instanceof SessionHandlerInterface)
{
if (is_php('5.4'))
{
session_set_save_handler($class, TRUE);
}
else
{
session_set_save_handler(
array($class, 'open'),
array($class, 'close'),
array($class, 'read'),
array($class, 'write'),
array($class, 'destroy'),
array($class, 'gc')
);
register_shutdown_function('session_write_close');
}
}
else
{
log_message('error', "Session: Driver '".$this->_driver."' doesn't implement SessionHandlerInterface. Aborting.");
return;
}
// Sanitize the cookie, because apparently PHP doesn't do that for userspace handlers
if (isset($_COOKIE[$this->_config['cookie_name']])
&& (
! is_string($_COOKIE[$this->_config['cookie_name']])
OR ! preg_match('/^[0-9a-f]{40}$/', $_COOKIE[$this->_config['cookie_name']])
)
)
{
unset($_COOKIE[$this->_config['cookie_name']]);
}
session_start();
// Is session ID auto-regeneration configured? (ignoring ajax requests)
if ((empty($_SERVER['HTTP_X_REQUESTED_WITH']) OR strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) !== 'xmlhttprequest')
&& ($regenerate_time = config_item('sess_time_to_update')) > 0
)
{
if ( ! isset($_SESSION['__ci_last_regenerate']))
{
$_SESSION['__ci_last_regenerate'] = time();
}
elseif ($_SESSION['__ci_last_regenerate'] < (time() - $regenerate_time))
{
$this->sess_regenerate((bool) config_item('sess_regenerate_destroy'));
}
}
// Another work-around ... PHP doesn't seem to send the session cookie
// unless it is being currently created or regenerated
elseif (isset($_COOKIE[$this->_config['cookie_name']]) && $_COOKIE[$this->_config['cookie_name']] === session_id())
{
setcookie(
$this->_config['cookie_name'],
session_id(),
(empty($this->_config['cookie_lifetime']) ? 0 : time() + $this->_config['cookie_lifetime']),
$this->_config['cookie_path'],
$this->_config['cookie_domain'],
$this->_config['cookie_secure'],
TRUE
);
}
$this->_ci_init_vars();
log_message('info', "Session: Class initialized using '".$this->_driver."' driver.");
Above is the part of the Session.php file. I tried to add session_start(); on every function in the else statement as well as set_userdata function as people gave a solution but it didn't work. Session.php gets called from the construct file as below and then it makes a new session, which doesn't have UID. How would I be able to keep UID from the login part..?
public function __construct() {
parent::__construct();
$this->load->library('session'); --> this calls Session.php file
$this->load->model('member_model');
$this->load->model('setting_model');
$this->load->helper('iny_common_helper');
$this->load->helper('url');
if($this->session->userdata('uid')) {
$this->memberInfo = $this->member_model->get_member_infoByUid($this->session->userdata('uid'));
}
if($this->memberInfo->no) {
$this->member_model->memberInfo = $this->memberInfo;
}

I think you are under a slight confusion.
parent.location.reload() is a javascript construct that trigger the reload of the parent of the current window. In your case, it will trigger the reload of the login page, because you are not in an iframe embedded in a parent page, you are in a page, you have no parent.
You need to replace the code below with a redirect to the page that redirected to the login page (or the current home)
echo "<script>";
echo "parent.location.reload();";
echo "</script>";
You can use php or javascript.
php:
header('Location: https://example.com/');
javascript:
echo "<script>";
window.location.replace("https://example.com/");
echo "</script>";
I would use php :), in your case the else branch would become:
} else {
$userdata['uid'] = $result->uid;
$this->session->set_userdata($userdata);
header('Location: https://example.com/');
exit;
}
Do not forget tu replace the example.com with your correct url.
The exit (or die()) statement is important, should be present, also the header() function only works if it is the first output (no echo's, print's, etc before), otherwise you will need to use the javascript redirect.

Related

Does session_set_save_handler method will lose the session data?

How can I get the session data when use session_set_save_handler?
When I refreshed the page, all the session data lost if i use the session_set_save_handler. however,if i delete the session_set_save_handler, all is right!
There is the code
<?php
/*
Session open (called by session_start( ))
Session close (called at page end)
Session read (called after session_start( ) )
Session write (called when session data is to be written)
Session destroy (called by session_destroy( ) )
Session garbage collect (called randomly)
*/
function sess_open($sess_path, $sess_name) {
//print "Session opened.\n";
//print "Sess_path: $sess_path\n";
//print "Sess_name: $sess_name\n\n";
return true;
}
function sess_close( ) {
//print "Session closed.\n";
return true;
}
function sess_read($sess_id) {
//print "Session read.\n";
//print "Sess_ID: $sess_id\n";
return '';
}
function sess_write($sess_id, $data) {
//print "Session value written.\n";
//print "Sess_ID: $sess_id\n";
//print "Data: $data\n\n";
return true;
}
function sess_destroy($sess_id) {
//print "Session destroy called.\n";
return true;
}
function sess_gc($sess_maxlifetime) {
//print "Session garbage collection called.\n";
//print "Sess_maxlifetime: $sess_maxlifetime\n";
return true;
}
session_set_save_handler('sess_open','sess_close','sess_read','sess_write','sess_destroy','sess_gc');
session_register_shutdown('session_write_close');
session_start();
if(isset($_SESSION['foo']))
$_SESSION['foo'] = "have the foo data";
else $_SESSION['foo'] = "no foo data";
echo $_SESSION['foo'];
?>
It always output 'no foo data',when I refresh the page.
if I delete the
session_set_save_handler('sess_open','sess_close','sess_read','sess_write','sess_destroy','sess_gc');
session_register_shutdown('session_write_close');
it always output 'have the foo data'.
Who can tell me why? Very thanks!

Prevent duplicate code with checking sessions

I have three session levels:
session->is_logged_external
session->is_logged_admin
session->is_logged_staff
I have a small function bellow (checkLogin) that I call to display a message if they do not have the session needed to accesses the page.
As you can see I have commented out code at a attempt to create a function that checks if the session is in one of these categories if so let them see page if not display message.
public function checkLogin()
{
$logged_admin = $this->session->is_logged_admin;
//$logged_external = $this->session->is_logged_external;
//$logged_staff = $this->session->is_logged_staff;
if(!isset($logged_admin) || $logged_admin != TRUE) {
echo 'Im sorry, you do not have administrator pillages';
echo anchor('main/index', 'Return home');
die();
}
//else if(!isset($logged_external) || $logged_external != TRUE) {
//echo 'Im sorry, you do not have external pillages';
//echo anchor('main/index', 'Return home');
//}
//else if(!isset($logged_staff) || $logged_staff != TRUE) {
//echo 'Im sorry, you do not have staff pillages';
//echo anchor('main/index', 'Return home');
//}
}
This did not work so I commented the code out. My next idea was to create three functions one for each of the sessions and call what functions I need for each page within the controller however, this is basically the same code repeated 3 times but with different session names, Is this the right way of doing this ?
Thanks guys.
example of idea two
First Admin session function
public function checkLoginAdmin()
{
$logged_admin = $this->session->is_logged_admin;
if(!isset($logged_admin) || $logged_admin != TRUE) {
echo 'Im sorry, you do not have administrator pillages';
echo anchor('main/index', 'Return home');
die();
}
}
Second Staff session function
public function checkLoginStaff()
{
$logged_admin = $this->session->is_logged_staff;
if(!isset($logged_staff) || $logged_staff != TRUE) {
echo 'Im sorry, you do not have staff pillages';
echo anchor('main/index', 'Return home');
die();
}
}
and a third that would be external, then I could call each one when I need them, right?

two if statements in php

I have two seperate if statements, the first if statement is not working but the second one is.
The first if statement works on my other pages and I am unsure of how to properly code this as I am a beginner to PHP.
<?php
session_start();
if($_SESSION['loggedin'] != 'true') {
header("location:login.php");
}
if ($_SESSION['admin']=='N') {
header("location:errorpage.php");
}
?>
What is true in your conditions? It can be bool type or string type.
If You set like this:
$_SESSION['loggedin'] = TRUE;
$_SESSION['loggedin'] = 'true';
You have got two different variable sets.
You can compare it using == or === to include variable type.
For example:
$_SESSION['test_1'] = TRUE;
$_SESSION['test_2'] = 'true';
var_dump( $_SESSION );
array(2) { ["test_1"]=> bool(true) ["test_2"]=> string(4) "true" }
$_SESSION['loggedin']?
Why don't just clear every SESSION var on logout and if the SESSION vars are set => the user is logged in.
And use after the header(); an exit();
Try var_dump($_SESSION['loggedin']) and edit your question.
Or maybe your loggedin var is not a string but a boolean so you could do if(!$_SESSION['loggedin'])
Try using Boolean values rather than strings. I would also use a const for the admin variables. I would do the following;
$_SESSION['loggedin'] = true/false;
$_SESSION['admin'] = true/false;
public class Priviledges
{
public CONST Admin = 0;
public CONST User = 1;
public CONST Contributor = 3;
//change this to however you want to do it :)
public static function isAdmin($val)
{
if ($val == Priviledges::Admin)
{
return true;
}
else
{
return false;
}
}
}
then when you set the admin session variable you can go;
$_SESSION['admin'] = Priviledges::Admin;
if(!$_SESSION['loggedin'])
{
header("location:login.php");
exit()
}
else if (!Priviledges::isAdmin($_SESSION['admin']))
{
header("location:errorpage.php");
exit()
}
else
{ //do your stuff if none of these conditions are met.. }
Always add an exit() or die() after sending a "Location" HTTP header:
<?php
session_start();
if($_SESSION['loggedin'] !== 'true') {
header("location:login.php");
exit();
}
if ($_SESSION['admin'] === 'N') {
header("location:errorpage.php");
exit();
}
Check: php - Should I call exit() after calling Location: header?.
From aaronsaray blog:
Remember, just because the browser is smart enough not to show the
content, doesn’t mean that this isn’t dangerous. So, it’s a little
less dangerous say if this page is just showing a user search option
or some information. It is much more dangerous if this is a page that
executes an action. This is because the entire PHP page will execute
if you don’t put a die() statement.
On other cases, if you want a condition to be evaluated only when a previous condition is false, you may use a "else if".

Session in Yii application

I want to learn sessions in Yii, thus I created a simple login form. Also I want to "set" session in this project.
My login action
public function actionLogin()
{
Yii::app()->session['userid'] = "value"; // where i should put line ??
$model=new LoginForm('login');
if(isset($_POST['ajax']) && $_POST['ajax']==='form-reg')
{
echo CActiveForm::validate($model);
Yii::app()->end();
}
if(isset($_POST['regist']))
{
$model->username=$_POST['istiad'];
$model->password=$_POST['parol'];
if($model->validate() && $model->login()) {
$this->redirect(array( 'update','id'=>$this->getIdByUsername($model->username ) ));
/* $this->render(
'update',array(
'model'=> $this->loadModelByUsername($model->username ) ) );*/
}
}
else
$this->redirect(Yii::app()->user->returnUrl);
}
logout action
public function actionLogout()
{
Yii::app()->user->logout();
unset(Yii::app()->session['userid']); // also this,
Yii::app()->session->clear(); // this
Yii::app()->session->destroy(); // and this line ??
$this->redirect(Yii::app()->homeUrl);
}
p.s: PLEASE EXPLAIN ME what is the userid in unset(Yii::app()->session['userid']); ? I couldn't understand (because I'm new in Yii). It's just only a variable or any attribute of the db table name?
I copied the lines from this topic.
Thanks. Best regards.
Set session after validation user name and password. Like here..
if($model->validate() && $model->login()) {
Yii::app()->session['userid'] = "value"; //here
$this->redirect(array( 'update','id'=>$this->getIdByUsername($model->username ) ));
}
unset destroys the specified variable.
unset(Yii::app()->session['userid']);
Here userid is session variable. It is destroyed.
Yii::app()->session->clear();
clear() is used to remove all sessions.
After clear(), you need to remove actual data from server using
Yii::app()->session->destroy();

jquery & php + if session is dead an error is returned

I've noticed if the session is dead (on an Jquery AJAX PHP Request) the data returned is preceeded with an error message if the session is needed in the request.
How do other sites deal with this?
Similar code is shown below - eg: its using a SESSION variable in the code which doesn't exist as the session is dead.
public function internal($variable) {
if($_SESSION['data'] == $variable) {
echo TRUE;
}else{
echo FALSE;
}
}
Should I use isset to check if the variable exists?
Should I be coding for dead sessions?
thx
You need to add the isset also:
public function internal($variable) {
if(isset($_SESSION['data']) && $_SESSION['data'] == $variable) { //add here
echo TRUE;
}else{
echo FALSE;
}
}
Try this
public function internal($variable) {
if($_SESSION['data']!="" && $_SESSION['data'] == $variable) { //add here
echo TRUE;
}else{
echo FALSE;
}
}
You can also do like this,
public function internal($variable) {
if(!empty($_SESSION['data']) && $_SESSION['data'] == $variable) { // modify here
echo TRUE;
}else{
echo FALSE;
}
}

Categories