Give access priviliges in codeigniter - php

In codeigniter, I have function to restrict controller,
private function controllerAccess(){
$sessionArray = $this->session->userdata('logged_in');
if($sessionArray['type'] == 'ADMIN' || $sessionArray['type'] == 'SUPERVISOR'){
return true;
}
else{
return false;
}
}
I am preventing my index controller by doing this,
public function index(){
$system = new SYSTEM();
$this->controllerAccess() ? $this->dashboard() : $system->container('No Access');
}
The problem is, Do I need to do the same thing with each public method (controller)?
Because, by doing this: I can access child controllers. For example, I can not access index page for agent. but I can access: agent/dashboard, agent/validate, etc...
Is there any method to block entire controller?
Thanks.

I have no clue what you actually mean and I've been using CI for 2 years now. It might be me but.. You might want to use an authex library since you request the userdata in your controller, that's no good in my eyes.
You should be something like
$user = $this->authex->getSession();
And to check if the user is appropriate to view the page you just use this function
private function verifyUser() {
$user = $this->authex->getSession();
if ($user == null)
redirect('hub/notauthorized/', 'refresh');
}
and you call it in every public function where you want to check the user rights like this
$this->verifyUser();

just run the function in the constructor of your controller, and then the function will run everytime your controller is hit
class YourController extends CI_Controller {
public function __construct()
{
parent::__construct();
if(!$this->controllerAccess(){
//you got a false so redirect or whatever you want to do on negative
}
}
private function controllerAccess(){
$sessionArray = $this->session->userdata('logged_in');
if($sessionArray['type'] == 'ADMIN' || $sessionArray['type'] == 'SUPERVISOR'){
return true;
}
else{
return false;
}
}
public function index(){
$system = new SYSTEM();
$this->controllerAccess() ? $this->dashboard() : $system->container('No Access');
}
}

Related

calling function inside function with same class and redirect in codeigniter

I am working on login and search functionality using CodeIgniter.
What Exactly I am doing?
When the user searches something in the search form and on submitting that form I put a check if the user is logged in then it will directly show the result & if the user is not logged in then it redirects the user to the login page and I saved the search data in session as search_session_data.
I have a controller which redirects user regarding the session. If the user came directly to the login page then the user is redirected to the dashboard after login. but if the user is coming from search page then the user is redirected to the search result page after login.
I have mentioned the problem inside the code with a comment.
This is the controller:
public function get_the_search_result() {
$search_session_data = $this->session->userdata('search_session_data');
$this->load->model ('my_model');
$result_data = $this->my_model->find_data_regarding_search_criteria($search_session_data);
$this->load->view ('app/app_statch_result',['result_data' => $result_data,]);
}
public function login_function() {
//necessary login code
if ($this->session->userdata('search_session_data')) {
//Here I want the if `search_session_data` available in session then
// user goest to `get_the_search_result` and view the
//'app/app_statch_result` but it is not working.
$this->get_the_search_result();
} else {
return redirect('dashboard');
}
}
So How do I redirect the user to app_statch_result from
login_function function?
Any suggestion regarding improvement is applicable. Thanks
If I were you, I would do the following:
Create login controller, or better, library and put all login logic inside that class. Then you can load that library from any controller... For example:
Sample library
class User_controll{
private $CI;
public function __construct() {
$this->CI = &get_instance();
}
public function check_user_data($username, $password) {
$tmpId;
// To increase security you can encrypt password
$user = $this->CI->db->from('users')->where(array('username' => $username, 'password' => $password))->get()->result();
if(count($user) == 1){
$this->CI->session->set_userdata('loggedIn', 1);
redirect('user_page');
}
}
protected function logout() {
$this->CI->session->set_userdata('loggedIn', 0);
}
public function isLoggedIn() {
return $this->CI->session->userdata('loggedIn') == 1;
}
}
Sample Controller
class User_page extends CI_Controller{
public function __construct() {
parent::__construct();
$this->load->library('User_controll');
}
public function index() {
if(!$this->user_controll->isLoggedIn()){
redirect('user_page/loginForm');
}
else {
// do whatever you want
}
}
}

CodeIgniter User is able to copy and paste URL and access main page

I am trying to build a simple login system using CodeIgniter. I have placed all of my functions into one controller and I have also placed a session check function called is_logged_in into the controller. However, the user can still copy and paste the URL once they have logged out and view the main page. It seems like my is logged in function isn't working. Am I missing something? It only works if I place a check in my header every time instead. Here is my code.
Controller file
function index()
{
$this->load->view('login');
}
function checklogin()
{
$this->load->model('user');
$query = $this->user->validate_login();
if($query)
{
redirect('portal/home');
}
else
{
$this->index();
}
}
function logout()
{
$this->session->unset_userdata('username');
$this->session->unset_userdata('is_logged_in');
$this->session->sess_destroy();
redirect($this->index(),'refresh');
}
function is_logged_in()
{
$is_logged_in = $this->session->userdata('is_logged_in');
if(!isset($is_logged_in)||$is_logged_in!=TRUE)
{
$this->index();
}
}
function home()
{
$this->is_logged_in();
$data['main_content'] = 'home';
$this->load->view('includes/template',$data);
}
function statements()
{
$this->is_logged_in();
$data['main_content'] = 'statements';
$this->load->view('includes/template',$data);
}
function about()
{
$this->is_logged_in();
$data['main_content'] = 'about';
$this->load->view('includes/template',$data);
}
}
?>
This is what I place into my headers that actually works instead of the function
<?php
if(!$this->session->userdata('is_logged_in'))
{
redirect('portal/index');
}
?>
User Model
<?php
class User extends CI_Model{
function __construct()
{
parent::__construct();
}
public function validate_login()
{
//$this->form_validation->set_rules('username', 'Username', 'trim|required');
//$this->form_validation->set_rules('password', 'Password', 'trim|required');
$username = $this->security->xss_clean($this->input->post('username'));
$password = $this->security->xss_clean(md5($this->input->post('password')));
$this->db->where('username', $username);
$this->db->where('password', $password);
$query = $this->db->get('accounts');
if($query->num_rows()==1)
{
foreach($query->result() as $row)
{
$sess_data = array(
'username'=>$this->input->post('username'),
'is_logged_in'=>TRUE,
'privilege'=>$row->privilege
);
}
$this->session->set_userdata($sess_data);
return true;
}
else
{
// echo $password;
}
}
}
?>
Also, how can I combine the commented out part in the user model with the next lines? I want an error message to be sent if no input is placed. Hope I can get help with this.
So much wrong in this. Do not, not ever, use a single controller for your application. Things will get pretty big, pretty fast, and then you have one unreadable blob of a file. Keep your application code normalized. That's why you are using MVC. If you then need a method accessible from every, or nearly every controller, then put this function into a base controller(MY_Controller i.e.), or a model, or a library, depending on the functionality of this method. But in your case, this is for a base controller. This wont help with your problem, but just a friendly suggestion.
The problem with your code is, the visitor hits the URL for method "statements" and this is what happens:
statements calls is_logged_in
is_logged_in determines user is not logged in and calls index
index loads the login view
statements method loads the statements view
After you check for log in, and determine that the user is not logged in, you have to prevent further execution of other parts of your code. I would suggest having is_logged_in method returning a bool(false) value, and the statements(and other methods) then stopping execution. But if you would separate your code like you should over multiple controllers, then maybe have the is_logged_in controller to redirect the user to the login page.

Simple way to check login session on all controller

I am storing admin login in session in login controller.
Now i want to check user login session on all other controller.
Can someone help with simplest way to do this?
i would use a hook here - because your session validation should be always the first thing before you do anything else
in your application/config/hooks.php type this
$hook['pre_controller'][] = array(
"class" => "AppSessionValidator",
"function" => "initialize",
"filename" => "AppSessionValidator.php",
"filepath" => "hooks"
);
After that create a File in application/hooks/
named AppSessionValidator.php and type this kind of code in
class AppSessionValidator
{
private $ci;
private $strRedirectUrl = "/login/";
private $currentController;
private $arrExludedControllers = array("login");
public function __construct()
{
$this->ci = &get_instance();
$this->currentController = $this->ci->router->class;
}
public function initialize()
{
if (!$this->ci->session->userdata("is_logged_in") && !in_array($this->currentController, $this->arrExludedControllers)
{
redirect($this->strRedirectUrl);
}
}
}
Since you want to check login session on all controllers, i think the best way to go would be to use the autoload file in config.
Create a helper file check_session.php in application/helpers/ and add this
<?php
//Get Current CI Instance
$CI = & get_instance();
//Use $CI instead of $this
//Check for session details here, here's an example
$user = $CI->session->userdata('user_id');
//Get current controller to avoid infinite loop
$controller = $CI->router->class;
//Check if user session exists and you are not already on the login page
if(empty($user) && $controller != "login" ) {
redirect('login/', 'refresh');
}
else {
return true;
}
?>
Now go to your autoload.php file at application/config/autoload.php and look for where your helper array is declared and add check_session to your helper list
$autoload['helper'] = array();
$autoload['helper'] = array('url','utility', 'check_session');
With that... you should be able to check sessions automatically on all controllers
while login:
$this->session->set_userdata('is_logged_in',TRUE);
Create model:
class Security_model extends CI_Model{
public function is_logged_in(){
if($this->session->userdata('is_logged_in')){
return true;
}
else{
$this->session->set_flashdata('feedback','Please login!');
redirect('login');
}
}
}
On your Any controller's Contructor:
$this->load->model('security_model');
$this->security_model->is_logged_in();

Laravel, Auth and logging out from a model

I'm currently using Laravel 5 Authentification, but I have edited it to allow me to connect to an API server instead of an Eloquent model.
Here is the code of my custom UserProvider:
<?php namespace App\Auth;
use Illuminate\Contracts\Auth\UserProvider as UserProviderInterface;
use WDAL;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Auth\GenericUser;
use Session;
class WolfUserProvider implements UserProviderInterface {
private $_loggedUser;
public function __construct()
{
$this->_loggedUser = null;
$user = Session::get('user');
if (!empty($user)) {
$this->_loggedUser = unserialize($user);
}
}
public function retrieveById($id)
{
return $this->_loggedUser;
}
public function retrieveByToken($identifier, $token)
{
return null;
}
public function updateRememberToken(Authenticatable $user, $token)
{
//dd('updateRememberToken');
}
public function retrieveByCredentials(array $credentials)
{
$user = WDAL::getContactCredentials($credentials['login']);
return $user;
}
public function validateCredentials(Authenticatable $user, array $credentials)
{
if($user->username == $credentials['login'] && $user->password == $credentials['password']){
$this->_loggedUser = $user;
Session::set('user', serialize($user));
return true;
}
else{
return false;
}
}
}
?>
This code might not be perfect as it still in early development ;-) (feel free to suggest me some ideas of improvement if you want to)
So when the user is logged, it has access to the whole platform and to several views and can communicate with the API server to display and edit data.
Sometimes, the API server can return "Invalid Session ID" and when my Model gets this message, the user should be redirected to the login page.
From a Controller it's really easy to handle I can use this code (logout link):
public function getLogout()
{
$this->auth->logout();
Session::flush();
return redirect('/');
}
But do you know how I should proceed from a Model ? I could of course edit all my controllers to check for the value returned by the Model to logout, but cannot it be done thanks to middlewares?
It seems to be really long to edit all my controllers, and this will imply a lot of duplicated code.
One of my tries was to throw an exception from the Controller, and catch in from the auth middleware.
It was not working, because I didn't write use Exception;
I'm now catching the exception, and can now redirect the user from the middleware.
Thank you anyway!

MVC - how to make the url not to change when a method is called

I have
login controller,model and view
url http://mySite/login
Now when i am at http://mySite/controller it shows the login form and then when i submit the form the run method is called so the url change to http://mySite/login/run
how can i stop this :?
P.S // I creat my own MVC following this tut : http://www.youtube.com/watch?v=2Eu0Nkpo6vM
login controller
class Login extends Conroller {
function __construct() {
parent::__construct();
}
function index()
{
$this->view->render('authentication/enter');
}
function run()
{
$this->model->run();
}
}
login model
class Login_Model extends Model
{
public function __construct()
{
parent::__construct();
}
public function run()
{
$sth = $this->dbh->connect()->prepare("SELECT UserID FROM users WHERE
username = :login ");
$sth->execute(array(':login' => $_POST['login']));
$data = $sth->fetch();
$count = $sth->rowCount();
if ($count > 0) {
// login
Session::set('loggedIn', $_POST['login']);
header('location: ../dashboard');
} else {
echo 4;
}
}
}
withour .htacces
the url is
http://mySite/index.php?url={controller name}
or
http://mySite/index.php?url={controller name}/{some method from the contoller}
Without watching that entire video or wondering too hard why you're re-inventing the PHP MVC wheel, here's my best guess.
Change your view's form to submit to the index action
<form method="post" action="login" ...
In your index action, detect a POST request and run the model's run() method from there
function index()
{
if ($this->request->isPost()) { // seriously, I'm just guessing here
$this->model->run();
}
$this->view->render('authentication/enter');
}
A couple of notes...
Don't do controller tasks (ie redirecting) from the model
Always exit; after sending a Location response header
Drop this mess and try a proven and tested MVC framework like Symfony or Zend

Categories