codeigniter sess_destroy() not working properly,what m i doing wrong? - session-variables

I am a newbie in codeigniter. I am using an an login form to login as an admin. When the admin logs in with the correct user name and password s/he is directed to the home page with a session variable.and then if he clicks the log out button the session is supposed to be destroyed and redirect the user to log in page i.e log in form page.
The 1st controller is admin:
<?php
class Admin extends CI_Controller
{
function index()
{
$data['main_content'] = 'admin/log_in';
$this -> load -> view('includes/admin/admin_template', $data);
}
function log_in()
{
$this->load->model('admin_model');
$query = $this -> admin_model -> validate();
if ($query)// if the user's credentials validated...
{
$data = array('user_name' => $this -> input -> post('user_name'), 'is_logged_in' => true);
$this -> session -> set_userdata($data);
redirect('admin/home/admin_home');
} else// incorrect username or password
{
$this -> index();
}
}
function log_out()
{
$this->session->sess_destroy();
redirect('/admin/admin','refresh');
}
}
The second controller is the home controller:
<?php
class Home extends CI_Controller
{
function __construct()
{
parent:: __construct();
$this->is_logged_in();
}
function is_logged_in()
{
$is_logged_in = $this -> session -> userdata('is_logged_in');
if (!isset($is_logged_in) || $is_logged_in != true)
{
$this -> load -> view('admin/forbidden');
}
}
function admin_home()
{
$data['main_content'] = 'home_view';
$this->load->view('admin/home_view');
}
}
The model is admin_model:
<?php
class Admin_model extends CI_Model
{
function __construct()
{
parent:: __construct();
}
function validate()
{
$this->db->where('user_name',$this->input->post('user_name'));
$this->db->where('password', $this->input->post('password'));
$query = $this->db->get('user');
if($query->num_rows==1)
{
return true;
}
}
}
Now, it supposed the user to logout and destroy the session, but if I click the back button of my browser I can get page back which was supposed not to be and the session is not destroyed.
please tell me what I am doing wrong here. I am using codeigniter 2.1.0.

after going through all the troubles and searching in various places i have finally found a proper solution to this question.the problem arrived because the browser was showing the cached pages.it was not the session that was creating the problem and it was working properly.
here is the solution:
in the home controller adding a function to clear the cache and calling it in the constructor function does the trick :)
here is the home controller with the solution:
<?php
class Home extends CI_Controller
{
function __construct()
{
parent:: __construct();
$this->is_logged_in();
$this->clear_cache();
}
function is_logged_in()
{
if (!$this->session->userdata('is_logged_in'))
{
redirect('/admin/admin');
}
}
function clear_cache()
{
$this->output->set_header("Cache-Control: no-store, no-cache, must-revalidate, no-transform, max-age=0, post-check=0, pre-check=0");
$this->output->set_header("Pragma: no-cache");
}
function admin_home()
{
$data['main_content'] = 'home_view';
$this->load->view('admin/home_view');
}
}
now thanks goes to this link " logout feature in code igniter ",here is where i have found the solution and it works perfectly :)

If you logout then although the session is destroyed, the session userdata remains for the duration of the current CI page build.
As a precautionary measure you should do:
function log_out()
{
$this->session->sess_destroy();
// null the session (just in case):
$this->session->set_userdata(array('user_name' => '', 'is_logged_in' => ''));
redirect('/admin/admin');
}
See: http://codeigniter.com/forums/viewthread/110993/P130/#662369

Related

How to check permissions in my controller

I'm new to Laravel and I'm writing a user management System on my own.
At this time,
I can CRUD permissions, roles and users,
I can check the permissions by the AuthServiceProvider#boot method like this:
public function boot()
{
Gate::before( function (User $user , $permission) {
// App administrator
if($user->getPermissions()->contains('appAll'))
{
return true;
}
// Permission check
return $user->getPermissions()->contains($permission);
});
}
In my AdminUserController, I can check the permissions like that:
public function index()
{
if( Gate::check('createUser') || Gate::check('readUser') || Gate::check('updateUser') || Gate::check('deleteUser')) {
return view('userMgmt/users/index', [
'users' => User::getUsersWithRolesWithTexts()
]);
}
else
{
return redirect(route('home'))->withErrors('You do not have required permission');
}
}
That is working well.
BUT
Is this the right way to wrap each controller method with:
if( Gate::check(...) ...) {
//Do what the method is supposed to do
}
else
{
return redirect(route('SOME.ROUTE'))->withErrors('SOME ERROR OCCURRED');
}
It would be nice if someone can give me some ideas.
Tank you
There is a controller helper function named authorize that you can call from any method in a controller that extends App\Http\Controllers\Controller. This method accepts the action name and the model, and it will throw an exception if the user is not authorized. So instead of the if...else statement, it will be one line:
public function update(Request $request, Post $post)
{
$this->authorize('update', $post);
// The current user can update the blog post...
}

Yii redirecting the admin and authenticated user to the desired page

I am new to yii. I want my admin upon login from webapp/user/login to redirect to the page I want which is localhost/webapp/story right now it is redirecting me to the index.php.
I have also registered a user and given that user a role which is authenticated and I want that when my user(the authenticated user) logs in via webapp/user/login then that user is redirected to index.php.
so there are two things:
1. redirecting admin to the desired page which is webapp/story.
2. redirecting the authenticated user to index.php.
I am using yii user and right extension. Please help me with this.
The code LoginController is below:
<?php
class LoginController extends Controller
{
public $defaultAction = 'login';
/**
* Displays the login page
*/
public function actionLogin()
{
if (Yii::app()->user->isGuest) {
$model=new UserLogin;
// collect user input data
if(isset($_POST['UserLogin']))
{
$model->attributes=$_POST['UserLogin'];
// validate user input and redirect to previous page if valid
if($model->validate()) {
$this->lastViset();
if (Yii::app()->user->returnUrl=='/index.php')
$this->redirect(Yii::app()->controller->module->returnUrl);
else// yehen par kuch aye ga according
$this->redirect(Yii::app()->user->returnUrl);
}
}
// display the login form
$this->render('/user/login',array('model'=>$model));
} else
$this->redirect(Yii::app()->controller->module->returnUrl);
}
private function lastViset() {
$lastVisit = User::model()->notsafe()->findByPk(Yii::app()->user->id);
$lastVisit->lastvisit = time();
$lastVisit->save();
}
}
I think could be somethings like this
<?php
class LoginController extends Controller
{
public $defaultAction = 'login';
/**
* Displays the login page
*/
public function actionLogin()
{
if (Yii::app()->user->isGuest) {
$model=new UserLogin;
// collect user input data
if(isset($_POST['UserLogin']))
{
$model->attributes=$_POST['UserLogin'];
// validate user input and redirect to previous page if valid
if($model->validate()) {
$this->lastViset();
// Old code commentede
//if (Yii::app()->user->returnUrl=='/index.php')
// $this->redirect(Yii::app()->controller->module->returnUrl);
//else// yehen par kuch aye ga according
// $this->redirect(Yii::app()->user->returnUrl);
// new code
if (UserModule::isAdmin()){
$this->redirect(array('story/index'));
}
else {
$this->redirect(Yii::app()->user->returnUrl);
}
}
}
// display the login form
$this->render('/user/login',array('model'=>$model));
} else
$this->redirect(Yii::app()->controller->module->returnUrl);
}
private function lastViset() {
$lastVisit = User::model()->notsafe()->findByPk(Yii::app()->user->id);
$lastVisit->lastvisit = time();
$lastVisit->save();
}
}

how to use SimpleSAMLphp in yii framework?

I have two project in yii framework and I want to use both project using SimpleSAMLphp with SSO. The condition, I need is if I login from the first project, i want access to the second project.
Thank you in advance.
First you load the SAML library by temporarily disabling the Yii autoloader. This is just to let you use the SAML classes and methods:
<?php
class YiiSAML extends CComponent {
private $_yiiSAML = null;
static private function pre() {
require_once (Yii::app()->params['simpleSAML'] . '/lib/_autoload.php');
// temporary disable Yii autoloader
spl_autoload_unregister(array(
'YiiBase',
'autoload'
));
}
static private function post() {
// enable Yii autoloader
spl_autoload_register(array(
'YiiBase',
'autoload'
));
}
public function __construct() {
self::pre();
//We select our authentication source:
$this->_yiiSAML = new SimpleSAML_Auth_Simple(Yii::app()->params['authSource']);
self::post();
}
static public function loggedOut($param, $stage) {
self::pre();
$state = SimpleSAML_Auth_State::loadState($param, $stage);
self::post();
if (isset($state['saml:sp:LogoutStatus'])) {
$ls = $state['saml:sp:LogoutStatus']; /* Only for SAML SP */
} else return true;
return $ls['Code'] === 'urn:oasis:names:tc:SAML:2.0:status:Success' && !isset($ls['SubCode']);
}
public function __call($method, $args) {
$params = (is_array($args) and !empty($args)) ? $args[0] : $args;
if (method_exists($this->_yiiSAML, $method)) return $this->_yiiSAML->$method($params);
else throw new YiiSAMLException(Yii::t('app', 'The method {method} does not exist in the SAML class', array(
'{method}' => $method
)));
}
}
class YiiSAMLException extends CException {
}
Then you define a filter extending the CFilter Yii class:
<?php
Yii::import('lib.YiiSAML');
class SAMLControl extends CFilter {
protected function preFilter($filterChain) {
$msg = Yii::t('yii', 'You are not authorized to perform this action.');
$saml = new YiiSAML();
if (Yii::app()->user->isGuest) {
Yii::app()->user->loginRequired();
return false;
} else {
$saml_attributes = $saml->getAttributes();
if (!$saml->isAuthenticated() or Yii::app()->user->id != $saml_attributes['User.id'][0]) {
Yii::app()->user->logout();
Yii::app()->user->loginRequired();
return false;
}
return true;
}
}
}
And finally, in the controllers you are interested to restrict, you override the filters() method:
public function filters() {
return array(
array(
'lib.SAMLControl'
) , // perform access control for CRUD operations
...
);
}
Hope it helps.
It can be done simply using "vendors" directory.
Download PHP Library from https://simplesamlphp.org/
Implement it in Yii Framework as a vendor library. (http://www.yiiframework.com/doc/guide/1.1/en/extension.integration)
Good Luck :)
I came across an Yii Extension for SimpleSAMLphp in github
https://github.com/asasmoyo/yii-simplesamlphp
You can load the simplesamlphp as a vendor library and then specify the autoload file in the extension.
Apart from the extension you can copy all the necessary configs and metadatas into the application and configure SimpleSAML Configuration to load the configurations from your directory, so you can keep the vendor package untouched for future updates.

how can I redirect login page if do not login in yii framework?

I have the actionLogin and create cookie like here :
public function actionLogin()
{
$this->layout = 'login';
$model=new LoginForm;
if(isset($_POST['LoginForm']))
{
$model->attributes=$_POST['LoginForm'];
if($model->validate() && $model->login()){
$cookie = new CHttpCookie('loginSuccess',$model->username);
$cookie->expire = 604800;
Yii::app()->request->cookies['loginSuccess'] = $cookie;
$this->redirect('/ktbeauty/index.php/categories/index');
}
}
$this->render('login',array(
'model'=>$model,
));
}
And Now I have some controllers which must check to login before access controllers, if not login, it must redirect to login page, how can I work for this ?
thankyou very much
in the action of your controller you can try something like this
public function actionGoToLogin()
{
if(!Yii::app()->user->isGuest)
{
// do something if user is authenticated
}
else
{
Yii::app()->user->loginRequired();
// or if you want you can redirect using Yii::app()->createUrl('controller/login');
}
}
In Controller, you have a function as below:
public function accessRules() {
Here you can define the actions and users who can access those functions.
If you are not logged in, then it'll redirected to login page by default.
This feature available by default in YII.
check this URL:
http://www.yiiframework.com/wiki/169/configuring-controller-access-rules-to-default-deny/

How to set default action dynamically in Yii

i want to change default action of a controller depends on which user is logged in.
Ex. There are two users in my site : publisher and author and i want to set publisher action as default action when a publisher is logged in, and same for author.
what should i do? when can I check my roles and set their relevant actions?
Another way to do this would be setting the defaultAction property in your controller's init() method. Somewhat like this:
<?php
class MyAwesomeController extends Controller{ // or extends CController depending on your code
public function init(){
parent::init(); // no need for this call if you don't have anything in your parent init()
if(array_key_exists('RolePublisher', Yii::app()->authManager->getRoles(Yii::app()->user->id)))
$this->defaultAction='publisher'; // name of your action
else if (array_key_exists('RoleAuthor', Yii::app()->authManager->getRoles(Yii::app()->user->id)))
$this->defaultAction='author'; // name of your action
}
// ... rest of your code
}
?>
Check out CAuthManager's getRoles(), to see that the returned array will have format of 'role'=>CAuthItem object, which is why i'm checking with array_key_exists().
Incase you don't know, the action name will be only the name without the action part, for example if you have public function actionPublisher(){...} then action name should be: publisher.
Another, simpler, thing you can do is keep the default action the same, but that default action simply calls an additional action function depending on what kind of user is logged in. So for example you have the indexAction function conditionally calling this->userAction or this->publisherAction depending on the check for who is logged in.
I think you can save "first user page" in user table. And when a user is authenticated, you can load this page from database. Where you can do this? I think best place is UserIdentity class. After that, you could get this value in SiteController::actionLogin();
You can get or set "first page" value:
if (null === $user->first_page) {
$firstPage = 'site/index';
} else {
$firstPage = $user->first_page;
}
This is a complete class:
class UserIdentity extends CUserIdentity
{
private $_id;
public function authenticate()
{
$user = User::model()->findByAttributes(array('username' => $this->username));
if ($user === null) {
$this->errorCode = self::ERROR_USERNAME_INVALID;
} else if ($user->password !== $user->encrypt($this->password)) {
$this->errorCode = self::ERROR_PASSWORD_INVALID;
} else {
$this->_id = $user->id;
if (null === $user->first_page) {
$firstPage = 'site/index';
} else {
$firstPage = $user->first_page;
}
$this->errorCode = self::ERROR_NONE;
}
return !$this->errorCode;
}
public function getId()
{
return $this->_id;
}
}
/**
* Displays the login page
*/
public function actionLogin()
{
$model = new LoginForm;
// if it is ajax validation request
if (isset($_POST['ajax']) && $_POST['ajax'] === 'login-form') {
echo CActiveForm::validate($model);
Yii::app()->end();
}
// collect user input data
if (isset($_POST['LoginForm'])) {
$model->attributes = $_POST['LoginForm'];
// validate user input and redirect to the previous page if valid
if ($model->validate() && $model->login())
$this->redirect(Yii::app()->user->first_page);
}
// display the login form
$this->render('login', array('model' => $model));
}
Also, you can just write right code only in this file. In SiteController file.