I have a login helper in my CodeIgniter project.
In every constructor of a controller I call a function to check if the user is logged in.
However when calling a function(getSetup) when logged out the login_view appears but also the other view db_manage for example. But I don't want to show content when not logged in.. How to fix this ?
Thanks
function __construct() {
parent::__construct();
if (!is_logged_in()) {
$this->load->view('login_view');
}
}
public function getSetup() {
$this->load->view("db_manage");
}
this way:
function __construct() {
parent::__construct();
if (!is_logged_in()) {
echo $this->load->view('login_view', null, TRUE);
exit();
}
}
yes, you can't exit in the c'tor that will stop Codeigniter from doing its render process from the output buffer. You can't really do this from the c'tor, its not really what the c'tor is for, its meant for setting up the class variables..
you should check the logged in from the method, and return the login view from there.
class My_Controller {
function ensureLoggedIn() {
if(!is_logged_in()) {
$this->load->view('login_view');
return False;
}
return True;
}
function getSetup() {
if(!$this->ensureLoggedIn())
return;
.... rest of method ...
}
}
#egig - whats the point in using a framework if your going to bypass the stack?!
Related
I am checking whether the user is logged in or not in constructor method, if not logged in then redirect to login method but it is looping infinite time.login method is defined in same controller.
issue:
1)For testing purpose just now I wrote same(login) method in 'Welcome' controller in that case it is working fine and redirect perfectly,after that I commented method in 'Welcome' controller and now login method is uncommented in user controller now it is not working
class User extends CI_Controller {
function __construct() {
parent::__construct();
is_logged_in(); // defined in custom helper
if (!is_logged_in()) {
redirect(base_url().'User/Login');
}
}
public function login(){
$this->load->view('loginpage');
}
}
//code in custom helper
function is_logged_in() {
$CI =& get_instance();
$user = $CI->session->userdata('id');
if (!isset($user)) {
return false;
}
else {
return true;
}
}
if your helper returns false your code never reaches the login function of the controller, it always passes by the constructor, which redirects and so on...
change this:
if (!is_logged_in()) {
$this->login();
}
now it calls the login function, if not logged_in(), otherwise it continues with the controller's index() function
Please Use Helper In Controller.
class User extends CI_Controller {
function __construct() {
parent::__construct();
$this->load->helper('name');
$checkLogin = $this->helperName->is_logged_in(); // defined in custom helper
if (!$checkLogin) {
redirect(base_url().'User/Login');
}
}
I guess you autoload your helper.
Maybe your helper function need to changed
function is_logged_in() {
$CI =& get_instance();
$user = $CI->session->userdata('id');
if (!isset($user) || is_null($user)|| empty($user)) {
return false;
}else {
return true;
}
}
Try this way. This is working fine.
Controller
function __construct(){
parent::__construct();
if(!is_login()){
redirect(site_url().'/User/login');
}
}
Helper
function is_login(){
//Your Logic
return false;
}
autoload.php
$autoload['helper'] = array('your_helper_class_name');
I am trying to redirect to controller index if not authorized the access to other functions within same controller. According to my coding it is looking like infinite loop. Please help me to do that.
class Customer_Dashboard extends CI_Controller {
public function __construct() {
$method= $this->router->fetch_method();
if ($this->session->userdata("cus_sel_comp")) {
}else{
if($method !="index"){
redirect(base_url()."customer_dashboard");exit;
}
}
}
public function index() {
// Here do some operations and let the user to select company and update the "cus_sel_comp" session variable. After set that session user can access the other controller functions.
}
public function other_function1() {
}
public function other_function2() {
}
}
My coding is as above. I need to do this using same controller. Problem is if that session not set there is a infinite loop.
Instead of redirecting return index function. See the code below
if($method !="index"){
return $this->index();
}
You are calling the same function and redirecting it to same method.
class Customer_Dashboard extends CI_Controller {
public function __construct() {
$method= $this->router->fetch_method();
if ($this->session->userdata("cus_sel_comp")) {
}else{
if($method !="index"){
redirect(base_url()."Customer_Dashboard/index"); // Redirect it to index if other method is invoked.
}
}
}
public function index() {
// Here do some operations and let the user to select company and update the "cus_sel_comp" session variable. After set that session user can access the other controller functions.
}
public function other_function1() {
}
public function other_function2() {
}
}
Also dont use base_url() instead of that define an path in config
base_url() has many other entries present which are un-necessarily called.
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 controller where in the constructor function, I want to check if the user is logged in or not. If not, I want an error message to be displayed, and for the script to exit without running any other function in the controller. This controller will only be called by ajax so the error would be displayed via JSON and then the javascript on the client will display it to the user.
How can I do this? If I did this:
function __construct()
{
if (! $this->loggedIn() )
{
echo json_encode( array('error'=> true) );
die;
}
}
I don't think the message would be displayed because codeigniter uses output buffering. Any ideas?
i understood that your problem is the client expects for a json type of response, so two options to use:
public function __construct(){
$_bad_login_msg = 'please try again' ;
parent::__construct();
if(!userLoggedIn()){
$this->output
->set_content_type('application/json')
->set_output(json_encode($_bad_login_msg));
//or just use
// echo json_encode($_bad_login_msg);
die;
}
}
http://codeigniter.com/user_guide/libraries/output.html
you won't have any buffering problems, the buffer contents will be sent to the client after the die...
The best way is to redirect the user to login page.
As mentioned here : https://stackoverflow.com/a/10399199/876117
public function __construct(){
parent::__construct();
if(!userLoggedIn())
$this->load->view('promptlogin');
$this->output->_display();
exit();
}
public function index(){
// one will never reach here unless he is logged in
$this->load->view('actualcontent');
}
I'm pretty sure you can just use something like this:
function __construct()
{
if (! $this->loggedIn() )
{
exit('Please login before visiting this page');
}
}
MY_Controller is your top level/parent controller so its all done in there because every other controller will extend it. So if you have an auth controller(which extends MY_Controller) you will have access to its logic.
So MY_Controller
class MY_Controller extends CI_Controller{
protected $_user;
public function __construct(){
parent::__construct();
$this->_user = $this->session->userdata('uid')
? find_a_user : NULL;
// if a session of user_id exists and is found in DB
// we have a live user
}
}
Auth
class Auth extends MY_Controller{
public function __construct(){
parent::__construct();
// we now have access to $this->_user
if($this->_user !== NULL) // we have active user
}
}
I think you should use flashdata and redirect to a controller with it. Then you can control if any flashdata comes in session, after that write it in view.
Can I pass a function to the view in CodeIgniter? The function basically checks if the session value is set. For example:
public function is_logged(){
$logged = $this->session->userdata('user_id');
if ($logged){
return true;
} else {
redirect('index');
}
}
Now i want to place this function on some of my view. so how can i pass this function to the view?
Thanks.
I would take a different approach, much like #atno said: you're using MVC pattern, so doing this kind of checks in your view is 'logically' wrong as well as going against a DRY approach.
I would do the check in controller, using the function I have in the model, and load the appropriate view according to the results:
class Mycontroller extends CI_Controller {
function index() //just an example
{
$this->load->model('mymodel');
if($this->mymodel->is_logged())
{
$this->load->view('ok_page');
}
else
{
$this->load->view('not_logged_view');
//OR redirect('another_page','refresh')
}
}
}
In your model:
function is_logged()
{
$logged = $this->session->userdata('user_id');
if ($logged)
{
return TRUE;
} else {
return FALSE;
}
}
If it's someting you need to do programmatically, for every method of a controller (like checking for being logged in), you can check inside the constructor:
function __construct()
{
parent::__construct();
// check code here
}
In this way you'll have the check before any method of the controller is called, i.e. upon controllers' initialization.
UPDATE:
using a model can be overkill here, you can just check what $this->session returns:
function index() { // or mypage() or whatever
if($this->session->user_data('user_id'))
{
$this->load->view('ok_page');
}
else
{
$this->load->view('not_ok_page');
}
}
You shouldn't be doing that. Just have this code directly in your layout, or just have it in your view.
You could also create a helper : http://codeigniter.com/user_guide/general/helpers.html