I'm trying to implement basic section that only a logged-in user can access. I overrided CI_Controller, as follow:
//file created in application/core/MY_Controller.php
class Auth_Controller extends CI_Controller {
function __construct(){
parent::__construct();
$this->load->library('session');
if ($this->session->userdata('user_logged') !== null){
redirect(base_url() . 'dashboard');
die();
} else {
redirect(base_url() . 'auth/login');
die();
}
}
And then I extend from Auth_Controller all the other controllers that are only available for the logged-in user, as follow:
class Dashboard extends Auth_Controller
{
public function __construct()
{
parent::__construct();
}
public function index()
{
$this->load->view('dashboardView');
}
}
But after the login is successful, it doesn't redirect to dashboardView.
Anyone knows what is really happening?
You are redirecting infinitely to the Dashboard controller in this part of the code:
if ($this->session->userdata('user_logged') !== null){
redirect(base_url() . 'dashboard');
die();
}
Use this instead (redirect to the login form if the user is not logged in):
class Auth_controller extends CI_Controller {
function __construct(){
parent::__construct();
$this->load->library('session');
// If the user is not logged in
if ($this->session->userdata('user_logged') === null){
// Redirect to http://yoursite/auth/login
// No need for the base_url function, redirect does it for you
redirect('auth/login');
// You don't have to exit/die, redirect() already does that
}
}
}
Opinions
If I check the null, will use like this != null. BUT in CI its a best option to check empty() rather null.
If I use redirect() will use it like this redirect('dashboard');
Code will be
if (!empty($this->session->userdata('user_logged'))) {
redirect('dashboard');
else {
redirect('auth/login');
}
Make sure your site will load without index.php in URL. If no search for .htaccess to your site.
Related
In my header view I wrote this code:
<?php
if($this->session->userdata('logged_in')) {
$query = $this->db->get_where('instructors', array('id' => $this->session->userdata('id')));
$insdatacheck = $query->row_array();
if($insdatacheck['name'] == '') {
redirect(base_url().'user/continueregistration');
} else { ?>
<script type="text/javascript">alert('test');</script>
<?php
}
}
?>
But it does not redirect to the following page. However, if I write this in the controller, it works properly. I wrote it in header view because I want to check it in every page where enters the user. How can I improve it and write in a proper way? Thanks in advance
I think instead of your header you should put your check inside your controller constructor.
class Test extends CI_Controller {
function __construct() {
parent::__construct();
// if not logged-in redirect to login page
if ($this->session->userdata('logged_in') == false) {
redirect('login'); // where you want to redirect
}
}
}
Another option is to create a base controller. Place the function in the base controller and then inherit from this.
To achieve this in CodeIgniter, create a file called MY_Controller.php in the libraries folder of your application.
class MY_Controller extends Controller
{
public function __construct()
{
parent::__construct();
}
public function is_logged_in()
{
$user = $this->session->userdata('user_data');
return isset($user);
}
}
Then make your controller inherit from this base controller.
class X extends MY_Controller
{
public function __construct()
{
parent::__construct();
}
public function do_something()
{
if ($this->is_logged_in())
{
// User is logged in. Do something.
}
}
}
First create session in the controller only,
Then we access session in any page,
$this->load->library('session');
$user=$this->session->userdata('logged_in');
if (!isset($user)) {
redirect(base_url().'user/continueregistration');
}
else {
<script type="text/javascript">alert('test');</script>
}
I am trying to load a controller (Dashboard) if session is ok.
if ($this->form_validation->run() == FALSE) {
if(isset($this->session->userdata['logged_in'])){
echo 'dashboard-01'; //test load
$this->load->controllers('Dashboard');//Not sure if syntax is ok.
Is this possible? are there better approaches on how to do this?
What I usually do is to load the controller and check on its constructor if the user has enough credentials:
class Sociedades extends CI_Controller {
var $globales = array();
function __construct()
{
parent::__construct();
$this->load->database();
$this->load->library(array('ion_auth','form_validation'));
// Elliot, if you see this, don't delete it!
$this->load->model('fSociety_model');
if (!$this->ion_auth->logged_in())
{
//redirect them to the login page if not authorized
redirect('auth/login', 'refresh');
}
}
// then the index and other methods...
}
By the way, I'm using Ben Edmund's IonAuth.
I am using this code for user which can't access page without login ,but it is not working to prevent the user .
if(! $this->session->userdata('id'))
return redirect('Login');
$this->load->view('public/dashboard');
Try this for start. But generally i use another strategy, i make the if statements in Views.
If this is not works for you, i will check further.
if(! $this->session->userdata('id')){
$this->load->view('Login'); }
else {
$this->load->view('public/dashboard'); }
What you could do is something like this
application / core / MY_Controller.php
<?php
class MY_Controller extends CI_Controller {
public function __construct() {
parent::__construct();
$route = $this->router->directory . $this->router->fetch_class();
// echo $route;
// Ignore any controllers not to be effected
$ignore = array(
'dirname/controllername',
);
// If the user has not logged in will redirect back to login
if (!$this->session->userdata('id') && !in_array($route, $ignore)) {
$this->session->unset_userdata('id');
redirect($this->config->item('base_url') . 'login');
}
}
}
On the controller change CI_Controller to MY_Controller
class Example extends MY_Controller {
public function index() {
}
}
if( $this->session->userdata('id') == "")
{
redirect('Login');
}
else
{
redirect('dashboard');
}
here Login and dashboard both are controller names.
I followed a tutorial on how to set up a login system for php apps in codeigniter. The logic when the user has session data is working great, but I have a problem when the user isn't logged in (f.ex. refreshes the page after a while). The view of "not_logged_in" gets executed twice when I were to call for the functin from constructor.
The following code works, but it means I gotta add the code for every function I add after.
class App extends CI_Controller {
function __construct()
{
parent::__construct();
}
private function logged_in()
{
$is_logged_in = $this->session->userdata('is_logged_in');
if (isset($is_logged_in) OR $is_logged_in)
{
return TRUE;
}
else
{
$data['title'] = 'Chyba přihlášení';
$data['main_content'] = 'not_logged_in';
$this->load->view('includes/template', $data);
return FALSE;
}
}
function index()
{
if($this->logged_in())
{
$data['title'] = 'APLIKACE';
$data['main_content'] = 'app_view';
$data['userid'] = $this->session->userdata('userid'); //get userid from session
$this->session->unset_userdata('userid'); //destroy the data
$this->load->view('includes/template' , $data);
}
}
function logout()
{
$this->session->sess_destroy();
redirect('login');
}
}
Now the real question, how would I go about putting the whole logic into a constructor without having to check for it in every function?
Make APPPATH.'core/MY_Controller.php' file and put authentication logic in constructor there. Than extend that class from every controller (you need auth logic).
class MY_Controller extends CI_Controller
{
public function __construct();
{
parent::__construct();
$this->check_login();
}
protected function check_login()
{
$is_logged_in = $this->session->userdata('is_logged_in');
//here should be *AND* instead *OR* logic
if (isset($is_logged_in) && !empty($is_logged_in))
{
return TRUE;
}
else
{
redirect('login/index');
exit();
}
}
}
Login.php controller:
class Login extends CI_Controller//NOT extending MY_Controller to avoid infinite loop
{
public function __construct();
{
parent::__construct();
}
public function index()
{
//here is login view
//and logic of preserving session
//with redirect to 'app/index' after successful login
}
public function logout()
{
$this->session->sess_destroy();
redirect('login');
}
}
App.php controller:
class App extends MY_Controller//extending MY_Controller to check login status
{
public function __construct();
{
parent::__construct();
}
public function index()
{
//here is app dashboard view
}
public function statistics()
{
//here is some other method that requires logged in user
}
}
I also would recommend you to check Ion_auth authentication system to see if suitable for you.
I have a callback function that checks my login details are correct - If they are wrong it returns an error (this is working fine). If the details are correct it should set the session $this->session->set_userdata('logged_in',TRUE); and then continue with the function login and be redirected to the dashboard - This redirect works fine.
In my function index(){} on any dashboard pages have the line
if($this->session->userdata('logged_in')) redirect('dashboard/home');
The line above is the one that is causing my 310 redirect but I am unsure why?
I am wanting to check if the user is logged in redirect to dashboard/home else go back to the login page home/login
Controller:
class Home extends CI_Controller {
function __construct() {
parent::__construct();
}
public function index()
{
//if($this->session->userdata('logged_in')) redirect('dashboard/home');
$data['contentMangement'] = $this->options_model->systemOptions();
$data['pageTitle'] = 'Login';
$data['message'] = "";
$this->load->view('_assets/header', $data);
$this->load->view('login', $data);
$this->load->view('_assets/footer');
}
public function login() {
$this->form_validation->set_rules('userEmail','Username', 'required|valid_email|trim|max_length[99]|xss_clean');
$this->form_validation->set_rules('userPassword','Password', 'required|trim|max_length[200]|xss_clean|callback__checkUsernamePassword');
if($this->form_validation->run() === FALSE) {
$data['contentMangement'] = $this->options_model->systemOptions();
$data['pageTitle'] = 'Login';
$data['message'] = validation_errors('<div class="alert alert-error">', '</div>');
$this->load->view('_assets/header', $data);
$this->load->view('login', $data);
$this->load->view('_assets/footer');
}elseif($this->form_validation->run() === TRUE){
redirect('dashboard/home');
}
}
function _checkUsernamePassword() {
$username = $this->input->post('userEmail');
$password = $this->input->post('userPassword');
$user = $this->user_model->check_login($username,$password);
if(! $user)
{
$this->form_validation->set_message('_checkUsernamePassword', 'Sorry the details you provided have not been found');
return FALSE;
}else{
$this->session->set_userdata('logged_in',TRUE);
return TRUE;
}
}
}
Here's what's happening.
Assume, I login correctly, in your login controller, you set logged_in = TRUE, and redirect me to dashboard/home. In the index() function at dashboard/home, if logged_in = TRUE (which it is) you redirect me to dashboard/home again. Once again, you check logged_in = TRUE, and redirect me again, and so on and so forth.
This is causing an infinite redirection loop which causes the 310 Error (Too many redirects).
You'll need to rework your login check. In index() in dashboard/home, do this:
if ($this->session->userdata('logged_in') === FALSE) redirect(site_url('dashboard/login'));
Now, when I visit dashboard home, you only redirect me away if I'm not logged in. This protects your dashboard home against non-authenticated users, while not throwing authenticated users into an infinite loop.
I think you first should create a MY_Controller to do that, what if one day you decide to change your session variable name from logged_in to logged? Will you open all your controllers and change its sessions?
Creating a MY_Controller you will make all other controllers, like Home_Controller extend the MY_Controller, like:
class Home extends MY_Controller
{
public function __construct()
{
parent::__construct();
}
}
Your MY_Controller:
//under /application/core/
class MY_Controller extends Controller
{
public function __construct()
{
parent::__construct();
if(!$this->session->userdata('logged_in'))
redirect('login');
}
}
Of course that on your Login_Controller you will extend Controller and not MY_Controller or you'll be on a infinite loop.