CodeIgniter global function - php

Where can I place my "global" function, which will check, if user is logged in?
Because I want to do something like: user is able to browse some pages only when the function isLogged() returns TRUE, and I'd have to use it in some views, that's why it should be a "global" function, which I can access from anywhere.
Is that possible? Or there is any better solution for this?

You should probably put it into a Library, and autoload the library. When you need to use the "logged_in" flag in a view, pass it in from the controller. Example:
application/libraries/Auth.php
<?php defined('BASEPATH') OR exit('No direct script access allowed');
class Auth
{
public function is_logged_in ()
{
// Change this to your actual "am I logged in?" logic
return $_SESSION['logged_in'];
}
}
application/config/autoload.php
...
$autoload['libraries'] = array(
...
'auth',
...
}
`application/controllers/welcome.php
<?php ...
public function index ()
{
$view_data = array
(
'logged_in' => $this->Auth->logged_in()
);
$this->load->view('my_view', $view_data);
}
application/views/my_view.php
<? echo $logged_in ? 'Welcome back!' : 'Go login!' ?>

Are you using an authentication library? If not I'd suggest one.
They come with functions like that.
Tank Auth for example has: is_logged_in() , which does exactly what you want!
http://www.konyukhov.com/soft/tank_auth/
For more info about which library to use you should check out this answer which compares all libs:
https://stackoverflow.com/a/476902/576223
If you don't want an authentication library you can do as suggested by Joe

you can use MY_controller with all function needed on every page of your website. and inherit all controllers from it. read this oficial wiki

Related

codeigniter login and user session

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/

Codeigniter: use auth in core base controller is it a good practice?

im doing this;
example core/MY_CONTROLLER.php
private $action_user=null;
public function __construct()
{
parent::__construct();
##listen for post attempts;
$this->validate();
##set action_user; return null if no session else return user object
$this->action_user = $this->session->userdata('loged_user');
##extra check step
if($this->user->pwd_has_changed($this->action_user)){
$this->session->sess_destroy();
alerts('error','the password you used to login has changed ! please relogin');
return $this->failed_login();
}
}
public function alerts(){return die(json_encode(alerts()));}#a helper function.. just ignore it for this example
public function logout(){$this->session->sess_destroy();redirect();}
#AUTH
private function failed_login(){
//$callers=debug_backtrace();
alerts('warning','failed login');//.' '.$callers[1]['function']);
ob_clean();//clear flush just to make sure !
if($this->input->is_ajax_request())$this->load->view('base/ajax/landing');
else $this->load->view('base/landing');
die($this->output->get_output());//kill request and load landing in same uri. this in case he attempt login again he will be at same url; also helps with partials views
}
private function success_login(){
unset($_POST['login'],$_POST['password']);
alerts('success','welcome '.$this->action_user->login);
//nothin much to do.. just dont die
}
private function validate(){
//listen to posts if so logout and relog in
if( !$this->input->post('login') || !$this->input->post('password'))return FALSE;
$this->session->sess_destroy();#destroy session
#1. validation
$this->form_validation->set_rules('login', 'User Login', 'required|min_length[4]|max_length[12]|xss_clean');
$this->form_validation->set_rules('password', 'Password', 'required|min_length[4]|max_length[12]|xss_clean');
#1.2 Failed validation
if( ! $this->form_validation->run() )return alerts('error',$this->form_validation->error_string(),false);#set message and return false
#2. Login
$this->user->login(set_value('login'),set_value('password'));
//i dont want it to return anything ! $this->user->login should set messages of success OR fail + set user session
}
public function auth($role = null){
if(!isset($this->action_user->id))
return alerts('error',"this is a users restricted area",$this->failed_login());
//ACCESS LEVELS CONDITIONS
if($this->user->in_group($this->action_user->id,$role))return $this->success_login();
return alerts('error',"this is a {$role} restricted area",$this->failed_login());
}
#END AUTH
now in my controller constructor; since MY_CONTROLLER constructor is called first; so i should hv retrieved $action_user object; or already attempted to log him in.
if i want to restrict a page i just add
$this->auth();
//or $this->auth('admin');
to its constructor and if user is not allowed page will die and send him my view page without redirect;
the reason im using such approach is let user be able to login,logout from any controller;
if he visit http://localhost/RANDOMECONTROLLER/logout he will still logout.. same for login.
also its helpful that sometimes when i get page partials by ajax; it will just return a landing page into this div with login form.
example
a statistics page have 4 widgets, 1 of them is only viewable by admin;
then when ajax fitch 4 widgets, it will show 3 and a div with login form saying you need to be an admin to login..
...
so do you think this is a good way to do this ? or is it bug gable spaghetti ** ?
This is not a good practice. The best practice is to create a Secure_Controller that extends MY_Controller. If you have a controller with auth you need to extend Secure_Controller, but if you have another without auth you need yo extend MY_Controller.
There are lots of libraries for codeigniter auth easy to extend and adapt to your requirements, for example Ion Auth.

CodeIgniter "default_controller" functions without controller name in URL

Forgive me if this is a "duh" question or if you need more information to answer, I am new to CodeIgniter and still haven't figured out a few things with best practices and such...
In routes.php I have $route['default_controller'] = "home"; so my default_controller is obviously "home".
Inside my home.php controller I have:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Home extends CI_Controller {
function __construct() {
// blah
}
function index(){
// blah
}
function login(){
// blah
}
}
Which works fine and everything, there is no problems with that. The only thing I can't figure out is if I want to access the login function, I currently have to go to www.blah.com/home/login. How can I change it so it just goes to www.blah.com/login, without creating a new controller (I would like to keep some of these one time base urls all in my default controller)? Is that even possible or do I just have to create a new controller?
If I just have to create a new one, is there a best practices for how many controllers you have, etc.
Documentation says: This route will tell the Router what URI segments to use if those provided in the URL cannot be matched to a valid route.
So use $route['login'] = 'home/login';
The way I have it set up is to have the index function act as the gatekeeper: if not logged in, show a login form view, if logged in, redirect to your (protected) home page. The login function is only accessed via post, when the user submits his login/pwd, and performs the login logic.
You need add a line to your application/config/routes.php file
$route['login'] = "home/login";

can one controller send the user to another controller

I am really new to CodeIgniter.
I am trying to setup a website where the user must be logged in to view the pages. Coming from Java, I am taking the hierarchical approach to things.
My thought was to write my own Controller base:
<?php
class MY_Controller extends Controller
{
function Controller()
{
parent::Controller();
if(!$this->quickauth->logged_in())
{
//they need to login, send them to the login page.
}
}
}
?>
Now I can write controllers which extend it and I will be sure that they will always be logged in.
Here is the outline for the login page:
<?php
class login extends Controller
{
function index()
{
//Lets just double check, they might not have to login.
if ($this->quickauth->logged_in())
{
//send them to the main controller
}
}
}
?>
Well as you can see I have gotten this far. What do I need to replace:
1. //send them to the main controller
2. //they need to login, send them to the login page.
with?
Is there a better way of doing this?
Thanks,
Blake
Redirection is easy.
Just use:
redirect('controller/method');
Yes, load the url helper to access the redirect function.
$this->load->helper('url);
Since the url helper is used a lot, you should autoload it in config/autoload.
if you load the 'url_helper' you've got a redirect function in there. Read the docs about the url helper for more information.
You could also use soemthing like this
function is_logged_in()
{
$is_logged_in = $this->session->userdata('is_logged_in');
if (!isset($is_logged_in) || $is_logged_in != true)
{
echo 'You don't have permission to access this page. Login';
die();
//$this->load->view('login_form');
}
}
You could build on this

How to make some pages not available when a user is logged in

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.

Categories