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();
Related
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.
I'm trying to send the session variable to another controller but when i use r_print() it shows nothing and there is condition applied which returns null.
<?php
// library/login_lib.php
class Login_lib
{
public function logged_in()
{
$CI = & get_instance();
return ($CI->session->userdata('userdata')['is_logged_in'])
? $CI->session->userdata('userdata')['is_logged_in'] : Null;
}
}
?>
<?php
// another file common_helper.php
if( !function_exists('authentication_user') )
{
function authentication_user()
{
$CI = & get_instance();
if( !$CI->login_lib->logged_in() )
{
$CI->session->set_flashdata('error', 'Please login with username and password');
if( $CI->input->is_ajax_request() )
{
echo 'session_expire';
die();
}
else
{
redirect();
}
}
}
}
There is another controller called Dashboard where i calling the above function authentication_user(). What i want now i want to call true from the login_lib which i am not actually. I don't know why its blocking to view the Login session.
Thanks in advance
return $CI->session->userdata('is_logged_in') ? $CI->session->userdata('is_logged_in') : Null;
syntax for getting session data in codeigniter is
$this->session->userdata('session_key');
I'm trying to modify the below code snippet / function hook to disable registration if the user is logged in.
<?php
add_filter("gform_disable_registration", "disable_registration", 10, 4);
function disable_registration($is_disabled, $form, $entry, $fulfilled){
//check form id and if not the form being checked status passed in to function
if ($form["id"] != 160)
return $is_disabled;
//check submitted values to decide if registration should be stopped
if ($entry["4"] == "No" && $entry["5"] == "No") {
//disable registration
return true;
}
else{
return false;
}
}
?>
I've tried the following to no avail:
add_filter("gform_disable_registration", "disable_registration", 10, 4);
function disable_registration($is_disabled, $form, $fulfilled){
//check form id and if not the form being checked status passed in to function
if ($form["id"] != 2)
return $is_disabled;
//check user login to decide if registration should be stopped
if( ! is_user_logged_in() ) {
return true;
}
else {
return false;
}
}
Hoping I can get this to work! Thank you.
Here is an article/snippet I wrote to do this... I didn't confirm if this is still the best way to accomplish this, but it certainly is a way that works. :)
http://gravitywiz.com/skip-user-registration-for-logged-in-users/
I believe there's a setting in the Form Settings to allow you require users to be logged in. Is there a reason you can't just use that?
I am using Codeigniter 2.1.4 and I have facing some issues with flashdata.
When I successfully submit record I can display the flashdata message. But if go to the other page from the page where flashdata message was displayed and then go back to previous page using browser back button it shows me flashdata message again.
How to clear flashdata message once it used?
I think its not the flashdata issue its cache problem. I am confused why this is happening. If its cache issue then how to remove it?
Below is code I have used,
//In the manage of controller
$this->session->set_flashdata('message', "Record updated successfully.");
// In the view of controller
$data['message'] = $this->session->flashdata('message');
// In the view page
echo $message;
Flash disappears only after next refresh
your code in controller is right
//In the manage of controller
$this->session->set_flashdata('message', "Record updated successfully.");
redirect('controller_name/function_name','refresh');
now in view use like this
if($this->session->flashdata('message')){echo $this->session->flashdata('message');}
hope it will work
Go to System->libries->Session->session.php
Find flshdata fuction and replace with this
public function flashdata($key = NULL)
{
if (isset($key))
{
$return= (isset($_SESSION['__ci_vars'], $_SESSION['__ci_vars'][$key], $_SESSION[$key]) && ! is_int($_SESSION['__ci_vars'][$key]))
? $_SESSION[$key]
: NULL;
unset($_SESSION[$key]);
return $return;
}
$flashdata = array();
if ( ! empty($_SESSION['__ci_vars']))
{
foreach ($_SESSION['__ci_vars'] as $key => &$value)
{
is_int($value) OR $flashdata[$key] = $_SESSION[$key];
}
}
unset($_SESSION[$key]);
return $flashdata;
}
You must redirect the page somewhere after $this->session->set_flash('item','value');
Example:
if ($this->form_validation->run() == FALSE){
$this->session->set_flashdata('error',validation_errors());
redirect(base_url().'user/login');
}
else{
$this->session->set_flashdata('success','Thank you');
redirect(base_url().'user/login');
}
Usually developer make a mistake when they submit data to same page. They set flash data but forget to redirect.
if you want to clear set_flash in controller or another view file, then you can use this simple code.
$this->session->set_flashdata('error', 'User not found...'); //create set_flash
destroy set_flash
//echo "<pre>"; print_r($_SESSION); die; //for check
if(isset($_SESSION['error'])){
unset($_SESSION['error']);
}
$this->session->set_flashdata('message', "Record updated successfully.");
After setting the flashdata redirect to some function or to the same function.
If you refresh in the same controller function the flashdata won't be deleted.Also going back and forth in the browser does't affect the flashdata.
to clear the flashdata redirect to another controller function and it will work.
As Code igniter does not offer the possibility to destroy the flashdata, you can work around this problem with a second fictitious call of the flashdata function without echo :
if ($this->session->flashdata('message')) :
echo $this->session->flashdata('message'); // First normal call
$this->session->flashdata('message'); // Second fictitious call
endif;
Looks like this will be fixed in 3.1.12: https://github.com/bcit-ci/CodeIgniter/pull/6013
It is php version issue. you need to modify your session file.
go to your Session.php file
find the _ci_init_vars function and add this "$value === 'old' ||" in the elseif condition.
or replace the function with following.
protected function _ci_init_vars()
{
if ( ! empty($_SESSION['__ci_vars']))
{
$current_time = time();
foreach ($_SESSION['__ci_vars'] as $key => &$value)
{
if ($value === 'new')
{
$_SESSION['__ci_vars'][$key] = 'old';
}
// Hacky, but 'old' will (implicitly) always be less than time() ;)
// DO NOT move this above the 'new' check!
elseif ($value === 'old' || $value < $current_time)
{
unset($_SESSION[$key], $_SESSION['__ci_vars'][$key]);
}
}
if (empty($_SESSION['__ci_vars']))
{
unset($_SESSION['__ci_vars']);
}
}
$this->userdata =& $_SESSION;
}
I have faced same problem when I have update php version 7 to php 8.
You can manually unset flash data just after display your error or success message.
$this->session->unset_userdata('err_msg')
it's work : https://github.com/bcit-ci/CodeIgniter/pull/6013#issuecomment-1316482414
This is an issue in newer version of php . You can fix it by replacing line 420 in system/libraries/Session/Session.php:
elseif ($value < $current_time)
with
elseif ($value === 'old' || $value < $current_time)
thanks,
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 ).