I'm developing a application in Code Igniter and a problem come by:
I have several functions that access the database, that are routed like this:
controller/function/variable
employess/deleteEmployee/4
So, anyone that put this on the url gonna delete the employee.
How can I manage to allow only a logged admin user to access this functions?
Is there a simple and well accepted way?
I must check every time if there is a user logged in and this user have the permission?
Regards,
Here is the URL for the reference...
https://ellislab.com/codeigniter/user-guide/general/hooks.html
Here is the simple example
Copy this piece of code as checksession.php and save it in /application/hooks
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Checksession
{
private $CI;
public function __construct()
{
$this->CI =&get_instance();
}
public function index()
{
if($this->CI->router->fetch_class() != "login"){
// session check logic here...change this accordingly
if($this->CI->session->userdata['userid'] == '' ){
redirect('login');
}
}
}
}
Copy this code in /application/config/hooks.php
$hook['post_controller_constructor'] = array(
'class' => 'checksession',
'function' => 'index',
'filename' => 'checksession.php',
'filepath' => 'hooks'
);
Enable hooks in /application/config/config.php
$config['enable_hooks'] = TRUE;
Hope this helps.
Good Luck and Happy Coding
Related
I'm developing a web application and i'm slightly confused by routes and how they work.
My web application has an admin area and the URL structure is as follows;
example.com/admin/view/form/123
My Admin controller looks like this;
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Admin extends CI_Controller {
public function index()
{
$data = array(
'title' => 'Admin Page'
);
$this->load->view('admin/index', $data);
}
public function view() {
$form_submission_id = $this->uri->segment(4);
$records = $this->Admin_model->getDetails($form_submission_id);
$data = array(
'title' => 'Form Details',
'records' => $records
);
$this->load->view('admin/view/index', $data);
}
}
I don't have any custom routes setup.
When I visit the following URL, I can see the page and corresponding data successfully;
example.com/admin/view/form/123
But, when I change the /form/ URL segment to something random like below I can still see the correct data;
example.com/admin/view/foo/123
Why is this?
I was expecting to see a 404 page?
What do I need to change in order to achieve what I want?
Perhaps i'm misunderstanding the logic and should have my controllers / routes setup differently?
Codeigiter URL has a structure as domain/controllerName/actionName/param1/param2 and so on. In your code URL example.com/admin/view/form/123 admin is controller, view is action name and form and 123 is the parameters which you passed using get method. You can access these parameters like $this->uri->segment(3).
Thus in your code:
It will not show any error as your function is not even using 3rd URI segment.
It will not show 404 page as it found correct controller and action.
To achieve domain related functionality, you need to either change for function code accordingly or need to use routes for this.
Hope it helps you to clarify this code.
Rohit Mittal answer is good and also,
You can change the view fuction in admin controller like as:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Admin extends CI_Controller {
public function view($form = null,$form_submission_id = null) {
if($form == "form" && $form_submission_id){
$records = $this->Admin_model->getDetails($form_submission_id);
$data = array(
'title' => 'Form Details',
'records' => $records
);
$this->load->view('admin/view/index', $data);
}
}
i have a login process where the user can view his dashboard after login.
The code in controller:
$adminid = $this->am->login_admin($email, $password);
if ($adminid) {
$admin_data = array(
'adminid' => $adminid,
'email' => $email,
'logged_in' => true,
'loggedin_time' => time()
);
$this->session->set_userdata($admin_data);
$this->session->set_flashdata('login_success', 'You are logged in');
redirect('Admin_dashboard/dashboard/' . $adminid);
} else {
$this->session->set_flashdata('login_failed', 'Invalid login!!');
redirect('admin/index');
}
After successful login the user is getting redirected to the following url
localhost/project/Admin_dashboard/dashboard/1
The issue is that if the user manually changes the url to something like this-
localhost/project/Admin_dashboard/dashboard/2
he is able to access the data of user whose id is 2 without login
To solve the issue i tried using the following codition in the view
<?php if($this->session->userdata('logged_in')): ?>
<? endif; ?>
However the 2nd url is still accessible
After login the user gets redirected to dashboard that also contains few other pages such as profile page, payment page etc which contains data that is only related to him.
I want that after login he should be able to see all his pages but not anyone else data by changing the url
Simply do one thing, instead of passing $adminid with the url, get the adminid with session, because you also storing values in session.
Instead of
redirect('Admin_dashboard/dashboard/' . $adminid);
Use this
redirect('Admin_dashboard/dashboard');
and inside the dashboard function in Controller use this
public function dashboard (){
$admin_data = $this->session->userdata('admin_data');
if(!isset($admin_data['adminid']) || empty($admin_data['adminid'])){
//Error message Login First
redirect('admin/index');
}
$adminid = $admin_data['adminid'];
//Proceed with this $adminid
}
Simply add this code to all controllers for maintaining user restrictions throughout all URLs.
Class Controller_name extends CI_Controller{
function __construct(){
parent::__construct();
if(!isset($this->session->userdata['logged_in'])){
//redirect login page
}
}
/**
Your Other Functions
**/
}
Let me know If you have anymore doubts..
set user session is valid or not in dashboard controller before load dashboard view and also check user session adminid value with uri segment value
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class MY_Controller extends CI_Controller {
function __construct() {
parent::__construct();
if (!$this->session->userdata('logged_in')) {
redirect('Login', 'refresh');
}else{
$uri_admin_val=$this->uri->segment(2);
$adminid=$this->session->userdata('adminid')
if($adminid!=$uri_admin_val){
redirect('Admin_dashboard/dashboard/' . $adminid);
}
}
}
}
And extend this my controller on dashboard and other controller
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Dashboard extends MY_Controller {
public $data;
public function __construct() {
}
}
hello all can any one help me to solve out this redirect issues in codeigniter.
i create a hook for login authentication .
below is my hook
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Login_auth {
function __construct() {
$this->CI = &get_instance();
if (!class_exists('session'))
{
$this->CI->load->library('session');
}
}
function auth(){
if(! $this->CI->session->userdata('islogin')
{
redirect(base_url().'loginCtrl/index');
}
}
the purpose to create hook is when i try to enter any url when not logged in it should redirect to login page
but it shows webpage has redirect loop
It will have a redirect loop as it's checking every page for a session. Including the login page.
You could do something like this;
if(!$this->CI->session->userdata('islogin')) {
// Not logged in. Are they trying to login?
if(!in_array($this->CI->uri->uri_string(), array('login', 'forgot-password')))
{
redirect('login');
}
}
This will check if the user is logged in. If their not, it will check the current uri_string and compare it to an array of "allowed" uri's array('login', 'forgot-password')
Hope this helps.
How do I change the content for a user when he logs in? I mean like enabling voting, changing "login" to "logout" etc.
What I think to do is to start the session when user logs in (I am preferring to start session only when user logs in, not all the time). Then add data to the session's cookie like-
//controller
$moredata = array(
'username' => $this->username,
'login' => TRUE
);
$this->session->set_userdata($modedata);
//redirect
Then in the other controller, where he has been redirected I check the following-
$login = $this->session->userdata('login');
if ($login==TRUE)
Depending on the 'if' condition I will pass a variable to the view, with the help of that variable I will forward only the div/sections which should be shown to a logged-in user.
The problem is, while performing the above comparison Codeigniter shows following error (remember I haven't added 'session' in autoload array yet)
Message: Undefined property: NameOfController::$session
And If I set following in the autoload file
$autoload['libraries'] = array('session');
then the "if ($login==TRUE)" comparison always shows FALSE.
What should I do?
If I were you, I'd place all your session checks in a base controller which all your other main controllers extend. This allows you to keep things DRY:
class BaseController extends CI_Controller {
public function __construct()
{
parent::__construct();
}
public function isLoggedIn()
{
// Will return true or false
return $this->session->userdata('login');
}
}
And in one of your functional controllers (the example below handles users):
class UserController extends BaseController {
public function __construct()
{
parent::__construct();
}
public function profile()
{
// Redirect if not logged in
if (!$this->isLoggedIn()) {
$this->redirect('some/other/page')
}
}
public function register()
{
// Show different HTML if not logged in
$data = array(
'isLoggedIn' => $this->isLoggedIn()
);
$this->load->view('register', $data);
}
}
The second method in UserController allows you to render different content in your view:
<? if ($isLoggedIn): ?>
<p>You're logged in!</p>
<? else: ?>
<p>Not logged in</p>
<? endif; ?>
On my last project we created a simple permissions helper that had functions to check for logged-in status and for privilege levels. Then we'd just call the helper's functions as needed from anywhere in the system. If the user is logged in and has privs for that content then they get the content - otherwise we'd redirect them to a registration or other error page. Since all of that logic is in the helper functions, we could wrap any permission-requiring code in a quick permissions call like if(is_logged_in()){code requiring login to access}.
I am doing project using zend framework-2. I want to restrict access to certain web directories through URL(if user without log in). if user tried to log in I need to redirect login page. this is what I do(rough idea not codes ).
AuthController
if(username and password ok){
setcookie('username', $username);
setcookie('password', $password);
//redirect to AlbumController indexAction
return $this->redirect()->toRoute('album', array('controller' => 'album', 'action' => 'index'));
}
so within AlbumControoler I added this code
public function indexAction()
{
if(isset ($_COOKIE['username']) && isset ($_COOKIE['password'])){
//some codes
}
else{
//if user not logged redirect to loogin page
return $this->redirect()->toRoute('auth', array('controller' => 'auth', 'action' => 'index'));
}
}
so if I use this way I need to add above codes every action. so my question is is this way ok? or is their easy way to do that?
As an answer for the actual question, you can do it in your controllers construct... something like this...
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class IndexController extends AbstractActionController {
public function __construct() {
$session = new \Zend\Session\Container('auth');
if ( !isset($session->name) || !is_string($session->name) ) {
echo "The following is not set:".$session->name;
header('Location: /user/login');
exit();
}
}
But as the previous posters noted cookies are really bad to use for something like this. This is a very generic example although the exit(); part is pretty important in this sense as you want to kill the script to not show any data in case the user hits escape on their browser. The exit(); will essentially kill out and not display anything.