I am using native PHP sessions ($_SESSION) with CodeIgniter framework.
I have a "Login" controller loads view where user enters login and password.
After the user submits the login form, the "Login" controllers authenticate() method is called.
If everything is alright i add some data to $_SESSION array, then i redirect user to "Organisation" controllers myOrganisation() method.
I'm calling session_start() in Login/login() , Login/authenticate() and Organisation/myOrganisation() methods, but still the session is not passed, because in myOrganisation() method the session is new.
I tested my cookies functionality with creating 2 test php pages, where i just echo session id. It works perfectly.
Maybe i am not putting session_start() in all places it needs to be? (i put them in all controllers methods).
Login Controller:
class Login extends CI_Controller {
public function index() {
session_start();
$this->load->view("Login/index", $data);
public function authenticate() {
session_start();
$_SESSION['login'] = $login; // everything is alright, redirect
header("location: ".base_url()."Organisations/MyOrganisation");
Organisation controller:
public function MyOrganisation() {
session_start(); // here session is a new one, not passed
if(isset($_SESSION['login'])) {
I don't know what was wrong with the session_start() placements that i did, but the one thing that solved the problem was to place it in index.php in main folder
session_start() can also be specified in a constructor, not every method in a class. That means both your controllers can have this:
function __construct () {
ini_set("session.gc_maxlifetime", 14400);
ini_set("session.cookie_domain", .yourdomain.com);
session_set_cookie_params(14400, '/', .yourdomain.com);
session_start();
}
The first 3 lines in a constructor are to make sure the session cookie is valid for a long time and under you domain.
Besides that (and not closed index() and authenticate() methods), where's $login coming from?
Related
I am new to codeigniter framework and I don't really get how does the built-in session works. What I want is that when the session expires the user will be redirected to login page. I checked the answers in google and other stackoverflow questions and tried every code in their but it does not work. In the native php session I only need to specify that if the session expires in the given time then redirect but when I applied it in codeigniter it does not work. I don't know also how to retrieve the session expiration value in config to compare it to the current time accumulated by the user during his/her logged session. Please help....
This is in function in controller
public function check_session()
{
$logged_in = $this->session->userdata('logged_in');
if(!$logged_in)
{
$this->logout();
}
}
And this is the ajax:
setInterval(function(){
$.ajax({
type: 'POST',
url: "<?php echo site_url('tms/check_session');?>",
success: function(data){
console.log(data);
}
});
},300);
First, create a core Controller under application/core. You can call it MY_Controller.php
Here is an example for MY_Controller.php:
class User_Controller extends CI_Controller {
public function __construct()
{
parent::__construct();
if ($this->session->userdata['logged'] == TRUE)
{
//do something
}
else
{
redirect('login'); //if session is not there, redirect to login page
}
}
}
Create your Controller Classes like below:
class Someclass extends User_Controller
Also you should pass a value which called "logged" in your session array. E.g:
$session = array('id' => $id, 'logged' => TRUE);
$this->session->set_userdata($session);
Now, if session ends, system will redirect user to login page. If you want to make this session control thing via JavaScript, you should write some code for it. By the way, I'm not suggesting this. You don't need to increase your system's workload. With my code, if a session ends when user want to visit another page, system will kick him out.
public function check_session()
{
if(!$this->session->userdata['logged'])
{
redirect('someurl');
}
}
Is there somewhere in codeigniter where I could configure an automatic redirect to my root page if the user's session is expired (I am not trying to extend the session expiration's time)?
Situational example:
User logs in, leaves page idle for one day, returns to page that
requires validated session and sees PHP errors everywhere.
I'd prefer for anything in this situation to be redirected to my root login page.
Thank you!
Use below code in each function and place your function code inside the if loop. This will be use full for you. Thank you .
$this->load->helper('url');
if($this->session->userdata('logged_in'))
{
// You function code should be placed here .
}
else{
redirect(site_url(),'refresh');
}
put this content into your constructor function because when the controller run constructor will execute first.
function __construct() {
parent::__construct();
if(empty($this->session->userdata("login_session_user")))
{
redirect(site_url(),'refresh');
}
}
I built an user login to my site by this guide:
http://www.iluv2code.com/login-with-codeigniter-php.html
I have few question about session's
I need to put the session_start(); in every controller or there is a way in codeigniter that it will automaticlly be in all controllers? (should I do that?)
and there is a other way rether to put in every function that:
if($this->session->userdata('logged_in'))
{
//function code
}else{
//If no session, redirect to login page
redirect('../login', 'refresh');
}
or should I do that for every controller function (for example if I have controller named page and he have the functions :index,edit,view I need to put it for every one of them?
and last question, I have logout button on the top of every page called by view/header
should I also put this function:
function logout()
{
$this->session->unset_userdata('logged_in');
session_destroy();
redirect('home', 'refresh');
}
in every controller or I can do it a "golbel" function in some way?
EDIT:
I use this in hooks.php:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/*
| -------------------------------------------------------------------------
| Hooks
| -------------------------------------------------------------------------
| This file lets you define "hooks" to extend CI without hacking the core
| files. Please see the user guide for info:
|
| http://codeigniter.com/user_guide/general/hooks.html
|
*/
$hook['post_controller_constructor'] = array(
'class' => 'SessionData',
'function' => 'initializeData',
'filename' => 'loginHelper.php',
'filepath' => 'hooks',
'params' => array()
);
and this in loginHelper.php:
<?
class SessionData {
var $CI;
function __construct(){
$this->CI =& get_instance();
if(!isset($this->CI->session)) //Check if session lib is loaded or not
$this->CI->load->library('session'); //If not loaded, then load it here
}
function initializeData() {
// This function will run after the constructor for the controller is ran
// Set any initial values here
if(!$this->CI->session->userdata('logged_in')){ //call session methods with super object
redirect('../login', 'refresh');
}else{
$data['user'] = $this->CI->session->userdata('logged_in');
}
}
}
?>
/* End of file hooks.php */
/* Location: ./application/config/hooks.php */
the user['data'] not created in all the pages. where am I wrong?
For your second question about logout, I usually put the logout function in a User controller and call it as Log Out.
For your first question, I saw a tutorial how you do user login in a controller and extend that controller in your regular controller, thats how you avoid login check in every function. I am trying to find that tutorial, once I get it, I'll share it, but the concept is like that way.
you do not need to put the session_start(); in every controller!
You could simply start the session class in the autoload.php file in your config directory!
$autoload['libraries'] = array('database', 'session', 'encrypt');
Also, it is better to check if the user is logged in, inside the constructor function of the classes!
if(!$this->session->userdata('logged_in'))
redirect('loginController/loginFunction', 'refresh');
and to destroy all the sessions when logging out, you could use sess_destroy();
Initializing a Session
To autoload Session, open the application/config/autoload.php file and add the item you want loaded to the autoload array so: $autoload['libraries'] = array('session'); Yo don't use session_start(); and session_destroy(); at all.
Session Documentation:
https://ellislab.com/codeigniter/user-guide/libraries/sessions.html
Auto-loading Resources:
https://ellislab.com/codeigniter/user-guide/general/autoloader.html
To Check Login
Use Hooks to avoid chunky code dupplications and it is better practise. Navigate bottom of the page and read Hook Points so you get an idea. It is easy! Definitely learn hooks.
Logout
You answer explained here.
After alot of working I solved the problem with the login check.
I didn't use the hooks. I build a MY_Controller in core folder and exteds it in all my controllers expect from the login controller.
In the MY_Controller I use thie login check.
CodeIgniter core controllers:
https://philsturgeon.uk/blog/2010/02/CodeIgniter-Base-Classes-Keeping-it-DRY/
I'm doing a project in php mvc but without framework. I organized the files in this way:
Directory public: there are files accessible from the outside
Directory View: there are files .php but essentially only html
Direcory Model: contains the files related to the database connection, and classes that define the objects, for example, the class User.php
Directory Controller: contains a 'generic' class Controller and Controller classes more 'specific'
I creat a login page (View/login.php) with a form whose action value is public/index.php. In index.php there is this code:
$controller = new LoginController();
$view = $controller->invoke();
$view->render();
invoke() is a function in Controller/LoginController.php that reads the data entered by the user and controls them, if they are correct (there is user in the database with the username and password) then creates two global variables and make a redirect:
$_SESSION['logged_in'] = 1;
$_SESSION['username'] = $username;
$url = "../public/home.php";
header("Location: $url", true, 302);
exit();
public/home.php does this:
$controller = new HomeController();
$view = $controller->invoke();
$view->render();
HomeController is a class that extends Controller. The constructor of Controller see if there are the variables $_SESSION['logged_in'] and $_SESSION['username'].
If they not exists it makes a redirect to public/index.php.
My problem is that the row with header("refresh:0; url=../public/home.php "); does not redirect.
Explain: when I insert the correct data (registered user) redirects for a short time but then returns to home.php.
Instead it should redirect to home.php and stay there, do not go to index.php .
I also tried with header("refresh: 0; url = ../public/home.php"); but it's the same problem.
How can I solve this problem?
Thank you and sorry for my poor English!
Add php ob_start() function on top of the page. If you call ob_start() while another ob_start() is active. Just make sure that you call ob_end_flush() the appropriate number of times. If multiple output callback functions are active, output is being filtered sequentially through each of them in nesting order.
Ref: http://in2.php.net/ob_start
In CakePHP we can use $this->Auth->allow('someMethod'); to make a page viewable without having to login. How do I make some the same page is not viewable when a user is logged in? An example of this would be a register page which we want to be accessible without user logged in ... but not accessible once a user logged in.
I put $this->Auth->deny('someMethod') in isAuthorized() but it seems to me that if the method is in the allow list then isAuthorized is not called when we try to run that page.
Any input? Thank you
There are no complex rules like that built into Cake Auth. You'll have to manually check for conditions like this. It's very simple though:
// Controller
function register() {
if ($this->Auth->user()) {
$this->redirect(/* somewhere else */);
}
}
Contrary to mlevits answer, you don't need to store anything in the Session, the info is readily available from the AuthComponent itself. http://book.cakephp.org/view/387/user
There's also an example how to do it by dynamically using deny(), but that's not as clear in a simple case like this IMHO. http://book.cakephp.org/view/383/deny
Also, deny() produces an error message ("You're not authorized to access this location"), which is probably not what you want for the user experience in this case.
EDIT:
Wasn't aware that CakePHP used a different syntax.
You can then use the following to set the Session variable:
$this->Session->write('user_id', '<some_user_name>');
Then use this to redirect the user if they are logged in:
if ($this->Session->check('user_id'))
{
$this->redirect('http://google.com');
}
And then to destroy a Session use:
$this->Session->destroy()
More information about CakePHP Sessions
Thanks
You can check it in method beforeFilter in AppController to allow aplication-wide check. For example:
<?php
class AppContoller extends Controller {
var $components = array('Session', 'Auth');
function beforeFilter(){
$this->Auth->allow('register', 'home');
// Check if current action allowed to access without authorization and User has login
if(array_key_exists($this->params['action'], $this->Auth->allowedActions) && $this->Auth->user()){
$this->redirect(/* somewhere else */);
}
}
}
?>
Of course you can also implements it in some controller instead of AppController.