How to restrict controller page from direct access from url in Codeigniter? - codeigniter

I have used several codes for restricting direct access of controller page from url, but its not happening.
The below code in controller page is not preventing from direct url access. Is there any proper way to prevent from direct access from url?
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Cont extends CI_Controller
{
public function __construct()
{
parent ::__construct();
$this->load->model('test');
}
public function handle($function){
if($function=='abcd'){
$this->load->view('testpage');
}
}
}

You can use HTTP_REFERER which holds the information(address) about the page that referred you to the current page, if it's empty you can redirect it to your 404 page. Also, you should always check for $_SESSION and redirect if not set.
if( !isset($_SERVER['HTTP_REFERER'])) {
$this->load->helper('url');
redirect('/page404');
}
Alternatively, you can also use HTTP_X_FORWARDED_FOR, but it won't help you in AJAX request. Read more about it here and here.

You can use _remap() function inside your Controller, where we can define where to route the method.
The following code blocks all method call to that controller.
function _remap($method)
{
return false;
}
See the DOC here

From documentation
For the best security, both the system and any application folders should be placed above web root so that they are not directly accessible via a browser. By default, .htaccess files are included in each folder to help prevent direct access, but it is best to remove them from public access entirely in case the web server configuration changes or doesn’t abide by the .htaccess.
If you want to prevent direct access to specific methods then you can try
public function _handle(){ //adding _ before the method name
}
Or
private function handle(){ //private functions cannot access by url
}

Related

PHPCas composer package and Codeigniter 3

I am trying to make a Codeigniter 3 application to authenticate to a CAS server.
I installed the phpcas package with composer but I cant find any details or examples on how to do this. I want the access to this application to be only from authentication users.
I believe that I have to edit a config file but I cant find any to write down the cas server url, etc. Also, in the controller of the page, I have to call somehow the library but I need some example for that.
So the main question is how can i get to use phpcas inside my controller methods amd how to configure it?
I created a controller and have inside:
?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class AuthController extends CI_Controller {
public function actionLogin()
{
$this->module->casService->forceAuthentication();
$username = $this->module->casService->getUsername();
$this->module->casService->getAttribute('mail')
$this->module->casService->getAttribute('title')=='TEACHER';
//$auth->assign($casRole, $user->id);
}
public function actionLogout()
{
$this->module->casService->logout(Url::home(true));
// In case the logout fails (not authenticated)
return $this->redirect(Url::home(true));
}
}
I place to the controller file the line:
require_once(APPPATH . '/../vendor/autoload.php');
and I init with:
$phpCAS = new phpCAS;
phpCAS::client(CAS_VERSION_2_0, 'sso-test.sch.gr', 443, '', false);

CodeIgniter URI Routing: remove method name index from URL

I am working with CodeIgniter (V:2.2.6) and I have a simple class User with some basic methods like create, update, edit, delete and index. For the index function, I am using an argument $user (which is the second URI segment) in order to display some information regarding that user. So the default URL looks like:
/user/index/john
to display some information about the user 'john'.
Now, I want to remove the term 'index' from the URL, so that it looks like:
/user/john
For that purpose I have added the following rule in routes.php.
$route['user/(:any)'] = "user/index/$1";
It serves the purpose, but it prevents accessing other functions like /user/create and goes inside /user/index automatically. To solve this problem, I can not see any other way except manually adding routing rules like
$route['user/create'] = "user/create";
for each method of the User class, which is not cool at all. So, please can anyone suggest me a better way of routing under the current circumstances?
Here are my codes:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class User extends CI_Controller {
public function index($user = '') {
echo "index!";
}
public function create() {
echo 'create!';
}
}
Note: I have gone through the CodeIgniter documentation for URI Routing and another similar question here, but could not figure out a promising solution. And please don't suggest for CodeIgniter version update.
I'm not sure, if this is the answer you like, but i think it should work.
Just put this function in your user controller.
public function _remap($method)
{
if (method_exists($this, $method))
{
$this->$method();
}
else
{
$this->index($method);
}
}

How to redirect to the method of a controller after user doing authentication on codeigniter?

I am using the Default Controller to make the user authentication. What I am trying to do is whatever is the page the user request news/add or news/index or themes/all or maps/view, if he is not logged in, he or she will be directed to the log in page and then redirected to the page he wanted to go, not always the same page.
You can your the
CodeIgniter User Agent Library and Session Library to store and use the referring url. The user agent library is basicly accessing the $_SERVER['HTTP_REFERER'] value.
NOTE: from the php.net website:
Not all user agents will set this, and some provide the ability to modify HTTP_REFERER as a feature. In short, it cannot really be trusted.
so this is not a foolproof method.
if ($this->agent->is_referral()) {
$this->session->set_userdata('prev_url', $this->agent->referrer());
}
// later, when login is successful
$prev_url = $this->session->userdata('prev_url');
if( $prev_url ) {
redirect($prev_url);
}
one way is to do it in the constructor of your controller. that way they are redirected before going to the news/add etc.
so for example you create a model called "sentry" and a "getUser()" method to check the browser cookie to see if the user is authorized. if they are not authorized have it return false. if they are authorized have it return $user so then you have it available for your other methods.
function __construct() {
parent::__construct();
$this->load->model( 'sentry' );
if ( ! $this->user = $this->sentry->_getUser() )
{ redirect( '/login/', 'refresh' ); }
}
so then for example you could have $this->user->name etc etc available to any method in the controller. And $this->user will also automatically be available in all the view files of this controller.
I do this by extending my controller and I check in constructor if person is logged in or not, if person is logged in I save to the session current URL, and redirect person to the login page (if same constructor is applied (controller one) I make exception to not save current URL to the session) after logging in I call redirect function to the session variable.
How to extend your controller is done here http://philsturgeon.co.uk/blog/2010/02/CodeIgniter-Base-Classes-Keeping-it-DRY
note that when your controller is extended you use $this->data['variable_sent_to_view'] and you can omit second parameter of $this->load->view()
here is some example code assuming you know how your login controller works
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
class MY_Controller extends CI_Controller {
function __construct() {
parent::__construct();
$this->output->enable_profiler(FALSE);
if ($refer = $this->session->flashdata('refer')) {
$this->data['refer_page'] = $refer; // $this->data['refer_page'] is variable that you are interested in
unset($refer);
} else {
$this->data['refer_page'] = base_url(); //default refer_page
}
//check if user is NOT logged in
if (!$logged_in) {
$this->_setRefer(); //this is private function
}
// else dont care about it
}
private function _setRefer() {
$invalid_method = array('search', 'login'); // if method is 'search' or 'login' url will not save in session (it will stay same as was before)
$valid_refer = TRUE;
if (in_array($this->router->method, $invalid_method)) {
$valid_refer = FALSE;
}
if (!(count($_POST) > 0) && $valid_refer === TRUE && !$this->input->is_ajax_request()) {
$this->session->set_flashdata('refer', current_url());
} else {
$this->session->set_flashdata('refer', $this->data['refer_page']);
}
}
}
now in after succesful login redirect to $this->data['refer_page'], but note that login controller must by extended by MY_Controller.
this script also takes care about what happens if user made mistake and inserted wrong password (page will reload but "old" url stays)

use ion auth authentication for codeigniter in another controller

I am trying to build a web application with codeigniter. I have installed Ion Auth as my authentication model.
The default Auth.php controller authenticates the user and sets up the session.
<?php defined('BASEPATH') OR exit('No direct script access allowed');
class Auth extends CI_Controller {
function __construct()
{
parent::__construct();
$this->load->library('ion_auth');
$this->load->library('session');
$this->load->library('form_validation');
$this->load->helper('url');
$data['title']="Login Page";
$this->load->view("view_site_header",$data);
// Load MongoDB library instead of native db driver if required
$this->config->item('use_mongodb', 'ion_auth') ?
$this->load->library('mongo_db') :
$this->load->database();
$this->form_validation->set_error_delimiters($this->config->item('error_start_delimiter', 'ion_auth'), $this->config->item('error_end_delimiter', 'ion_auth'));
}
//redirect if needed, otherwise display the user list
function index()
{
// if not logged in - go to home page
if (!$this->ion_auth->logged_in())
{
//redirect them to the login page
redirect('auth/login', 'refresh');
}
// if user is an admin go to this page
elseif ($this->ion_auth->is_admin())
{
// if an admin, go to admin area
//set the flash data error message if there is one
$this->data['message'] = (validation_errors()) ? validation_errors() : $this->session->flashdata('message');
//list the users
$this->data['users'] = $this->ion_auth->users()->result();
foreach ($this->data['users'] as $k => $user)
{
$this->data['users'][$k]->groups = $this->ion_auth->get_users_groups($user->id)->result();
}
$this->_render_page('auth/view_users', $this->data);
} else
{
//redirect them to the default home page
$data['title']="IMS Home Page";
$this->load->view("generic/view_site_header",$data);
$this->load->view("generic/view_generic_nav");
$this->load->view("generic/view_content_generic");
$this->load->view("view_site_footer");
}
}
what I want to do is create a new controller for my application logic and leave the auth controller for authentication.
How can I make use of the auth controller to ensure my user is logged in when accessing my new controller? in addition I need the ession information to be available to the new controller.
my new controller, master_data has the following code:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Masterdata extends CI_Controller{
function index ()
{
$data['title']="Master Data Home Page";
$this->load->view("master_data/view_master_data_header",$data);
$this->load->view("master_data/view_master_data_nav");
$this->load->view("master_data/view_content_master_data_home");
$this->load->view("master_data/view_master_data_footer");
echo $this->session->userdata('username');
}
}
obviously the echo $this->session->userdata('username'); does not work as the new controller has no knowledge of the auth controller session.
any help appreciated as always.
Kind Regards,
First autoload the ion_auth library.
If u simply want to check if the user is logged-in, just check it in every controller's constructor u load
public function __construct() {
parent::__construct();
if (!$this->ion_auth->logged_in()) {
// redirect to login view
}
}
If u happen to have multiple groups , u can create a new controller inside application/core/MY_controller.This controller will check whether user is logged in.You can extend this base controller to create new controller.A very good explanation on this is given by David john.Check this link .
obviously the echo $this->session->userdata('username'); does not work as the new controller has no knowledge of the auth controller session.
Eh...if the session library is loaded, then yes...the controller calling it will be able to access the session variable $username.
The way we handle this is to create a new controller parent class like MY_Controller in the application/core directory. This class loads common libraries/packages (like session and ion_auth). You could also autoload the libraries and helpers.
Since ion_auth stores all of the user profile data in a session var, all you need (on subsequent, non-authenticated) pages is the session lib to retrieve session data about the logged in user.
You really should check for their auth status though, and fail gracefully:
if (!$this->ion_auth->logged_in()) {
// echo a login link
} else {
// echo session var for username
}
Something like that...
jcorrys approach should work. An alternative approach (which will give your entire application a great deal more flexibility is to use a modular layout - https://bitbucket.org/wiredesignz/codeigniter-modular-extensions-hmvc
You will have to do a bit of fiddling to get it to play nicely with ion auth, but following the instructions in this question worked for me: Using Ion Auth as a separate module in the HMVC structure (have a look at the forks of ion auth on git hub - I think someone may have already done it for you)
This approach will allow you to access any method in any controller from anywhere in your application (even from a view if you need to) using this kind of syntax: modules::run('module/controller/method', $params);
This will essentially allow you to develop the existing ion auth controller into a user management controller which you can access from any other controllers you create (nice and dry).

How to prevent to direct link access in Code igniter

How to prevent to direct link access in Code igniter
E.g.
http://localhost/myapp/admin/displayUser
There is no built in authentication library within CodeIgniter, although there are many well developed third party ones. My preference is for Ion Auth - http://benedmunds.com/ion_auth/.
However if you are simply referring to preventing access to some "private" controller methods, you should add an underscore to the beginning of the method name - this will mean it is not accessible via a url, only via other controller methods:
function _myprivatemethod() {
return true;
}
Create a library as authenticate.php having following code into it and add that library in autoload.php
class Authenticate
{
function Authenticate()
{
$CI = & get_instance();
if ($CI->session->userdata('USERID') == "")
{
$redirectlink = 'contoller function path to your login page';
redirect($redirectlink);
exit;
}
}
}
This my not help you but it might help someone else.
I did it by creating a hook that checks if the user is logged in . If they are not it redirects them to the home login controller.
if (!$this->session->userdata('logged_in')) {
redirect('user/login');
}
If you create a Auth_Controller that extends CI Controller then instead of extending CI Controller you can make all your apps extend your new Auth_Controller so they always redirect if the user is not logged in.
if (!$this->session->userdata('logged_in')) {
redirect('user/login');
}
this will perfectly work..
just remember to load the session library as well.
$this->load->library('session');

Resources