If a user is not logged in I would like to override the existing Controller and call the auth/login one instead keeping the browser URI in tact. (Every user has to be logged in to use the site)
I have tried a pre controller hook, but its too early. The auth library has not been instantiated by this point.
The post controller hook is too late as the target controller has been instantiated.
Editing the constructor of the library seems pointless also, as it has already been created.. So i am a little stuck..
Any ideas please? :)..
Thanks
I would override the default controller and extend in each controller. Create a new file: ./app/core/MY_Controller.php with the next code:
class Secure_Controller extends CI_Controller {
function __construct() {
parent::__construct();
/* replace this code with yours */
if( !$this->session->userdata('logged_in') ) {
redirect(base_url() . 'login', 'refresh'); // your login url
}
}
}
Then, use this code in each controller that you should be accessible by logged users
class Main extends Secure_Controller {
Have you considered just saving the URI to flashdata, redirecting the visitor to another controller (login page) and then just putting the referrer into a hidden form field? I'm doing the same thing with one of my sites using Codeigniter and it works fine. The only difference is that the URI is not intact during this process.
Perhaps the answer to this question will be the same for you ? CodeIgniter only allow access to certain controllers when logged in
(If so, don't forget to replace the "function className()" by "function __construct()" and "parent::Controller();" by "parent::__construct();")
Related
I have a User entity with a resetPassword property on it. It's boolean, if true the user should be redirected to a resetPassword form.
At the moment I have this logic in my DefaultController. When someone hits the index route the controller action checks for the flag and renders a resetPasswordType form when needed. It's OK but far from ideal: without cut/pasting code it won't apply to all routes.
What is the best practice to properly implement this?
I've had a few ideas:
An event listener like the one described here might do the trick. I have tried it, and I managed to get the user token and got the check to work but I'm not sure what the best way to render the formType is from there. Maybe I could just redirect to a route from the event listener, but again I'm not 100% sure on how to do this.
A custom userChecker. This would only work after login but that's OK in this case. Again, I have tried it, it worked, but I'm not sure on how to render the form from there.
Some sort of custom redirect after success but I'm not sure on where to actually do the check on the resetPassword flag in this case.
Any opinions/advice welcome.
Create MY_Controller.php in application/core:
class MY_Controller extends CI_Controller {
function __construct()
{
parent::__construct();
//do your works...
}
}
Then , extends all your controllers :
class your_controller extends MY_Controller {}
Your code will run befor any controller (extented from MY_Controller ) run.
In my controllers I'm limiting access by prefixing my functions with admin_ and then letting the AppController isAuthorized() function check if the user is an admin. Is there a way to do this with pages (from PageController)? We created an admin homepage (like a dashboard) which users cannot view if they are not logged in, but non-admin users CAN view it. I can't figure out how to prevent this.
What do you mean with pages? Something static served by the PagesController or a .htm(l) file located in your webroot?
If your case is the first thing, you can implement this logic for the Pages Controller.
If it is the second - the request doesn't go through CakePHP (or any other server-side script) at all, so no you cannot controll access to it through Cake.
If your situation is something else, then refine your question and I'd be happy to help.
As the comment suggests you're in situation No:1. In the class declaration of the PagesController it says:
class PagesController extends AppController {
this means that you can use any logic that is in AppController in whichever class that extends AppController. Thus you can use isAuthorized() in the PagesController.
All you need to do is create a method with a name the same as your "admin dashboard view" and allow access to it only for admins. Or just check the user role.
Assuming that the first parameter is the requested Page and you can catch it using this statement:
$this->request->pass[0];
you can use the isAuthorized function to solve your problem doing something like this...
public function isAuthorized()
{
$page = strtolower($this->request->pass[0]);
if ($page = 'admin_page')
{
if ( $this->Auth->user('Role.role_field') == 'Admin' )
{
return TRUE;
}
else
{
return FALSE;
}
}
else
{
// This will authorize users for the other pages
return TRUE;
}
}
Hope this helps. Always check the CookBook: sometimes you need to check the older Books for finding what you really need. Happy Coding!
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
CodeIgniter authentication + user privileges
I had 5 user type and have permission table in which i give differnt permission to different user . permission like is_view,is_delete,is_add etc . User access the feature according to these permission.
I complete Database. I want to check the permission given to user on each page before the controller is called.
You should either place your auth-logic in the constructor of the controller
OR
in the constructor of a base-controller (more DRY as you don't have to repeat the logic in all controllers).
I would create a new controller which extends the core controller. Place this file in application/core/
class MY_AuthController extends CI_Controller {
public function __construct() {
// Do your auth check in here, redirect if not logged in
}
}
Then all the pages that need authentication you just inherit this new controller. This file you just place in your regular controller-folder
class Admin extends MY_AuthController {
// All your controller goodness in here..
}
I advise you to read the following two articles:
1. Phil Sturgeon's post on Keeping It Dry.
Phil will introduce you to how to create parent controllers whose constructors will contain the session and potentially database logic. All controllers that you create thereafter should inherit from your custom controllers instead of the native CI_Controller.
Followed by....
2. Shane Pearson's CodeIgniter Base Classes Revisited.
Shane's article revamps Phil's technique and relocates your custom controllers from /core to /base and also utilizes a better __autoload()'er. This implementation allowed me, for instance, to use CodeIgniter's CLI class, whereas, Phil's bugged out.
To give you an idea - your code would look a little something like this once complete:
In /base/MY_In_Controller.php:
<?php
class MY_In_Controller extends CI_Controller{
function __construct(){
parent::__construct();
//things like:
//is the user even logged in? thank heavens I don't have to check this in every controller now. redirect if the session doesnt exist.
//query the database and grab the permissions for the user. persist them with $this->load->vars();
$this->data['perms'] = some_database_function();
$this->load->vars($this->data);
}
}
In controllers/manage.php:
<?php
class Manage extends MY_In_Controller{
function __construct(){
parent::__construct();
}
function index(){
$this->load->view('manage');
//and I can still access their permissions here and in the view.
print_r($this->data['perms']);
}
}
So, i have some problem.
I just want to create some website where visitor can interact with my site if they're registered.
Let say they've provided their username,email,password, blah..blah..blah...
And then after they provided their blah..blah..blah.. it will autologin (if their data is passed) to my site.
After they logged in my site, they must provided more data again, like they uploaded their profile picture, how they control their privacy in my site, like step by step registration.
I don't want they interact with my site, until they complete their registration.
How do i make every page in my site looks like registration page until they finished their registration.
It's not like i will give this kind of function right.
if(is_login()){
if(is_registration_complete()){
//you're free to go
} else {
// complete your registration first
}
} else {
//you're not logged in
}
In my every controller, if you know what I mean :)
How do I create this function globaly?
If their registration isn't complete, they will go to registration controller, in every routes.
If they complete their registration, they will go to the, yeah you know the default routes.
I'm so sorry if my English is bad, English isn't my native language, sorry for grammar mistakes :)
The easiest is probably to create a library with your checking function and then to include it in the Constructor of the impacted ControllerS :
class Blog extends CI_Controller {
public function __construct()
{
parent::__construct();
// Load the lib here or Autoload
$this->load->library('mylogincheckhelper');
$this->mylogincheckhelper->is_complete();
}
}
And then you do all the ckecks and routing in the Lib.
create a view with your post-registering stuff and make them conditionally visible. and include the view in your templates.
One way you can do it is to create a custom controller by extend the core CI_Controller. Then you can have your page controllers extend from your custom controllers. By extending, you inherit the functions of the parent, as well as run the parent constructor (or run it if you override it), making them "globally available" to whoever extends it.
//extend the core controller
class MY_Controller extends CI_Controller {
//override to provide additional functionality
public function __construct(){
//run the core controller
parent::__construct();
//then do your login and registration checks here
//you can put code here, call another function or load a helper class
//or better, redirect them to your registration page
}
}
//your page's controller extending from your custom controller
class Page extends MY_Controller {
//not overriding the constructor will execute the parent constructor
//every page that extends your extended controller will inherit it's functions
//and execute it's constructor
}
I am very, very new with MVC (just started yesterday) so this question is probably stupid, but I need to know how to check automatically if user is logged in on my functions that are in admin/user models.
I can put the checking in construct, this would help, but I have several models and maybe there is some even better way. I hope you will understand better what I want after you see my folder structure and code. Oh, and by the way - I use Code Igniter 2.0
Folders:
controllers/
../admin/
../../item.php
../../cat.php
Let's see my item.php file...
<?php
class Item extends CI_Controller
{
function Index()
{
//Checking if admin is logged in on every function is bad
/*
* Is it possible to somehow make all admin functions go through
* some kind of Admin class that will check automatically?
*/
$isLogged = $this->session->userdata('is_logged_in');
if ($isLogged == true)
{
$this->load->view('admin/item/main');
}
else
{
$this->load->view('admin/login');
}
}
function Add()
{
$this->load->view('admin/item/add');
}
function Edit()
{
$this->load->view('admin/item/edit');
}
function Delete()
{
$this->load->view('admin/item/delete');
}
}
I hope that this is easy question, thanks in advance :)
I would implement the login-function in CI_Controller.
Then I would set an protected variable in Item protected $loginRequired = true;.
In function __construct() or Item() I would call parent::isLoginRequired($this->loginRequired) which checks if a login is required.
I would also redirect to a specific login page with a parameter which redirects the user back to the page he needs to be logged in.
Make a new class, for example, My_Controller extends Ci_Controller and write some auth checker code in it... in controller file just extend My_Controller
what i usually do is -like Teeed recommends- Create my own controller Class which is between the CI_Controller and each controller you might create.
In that class (MY_Controller) you can instantiate a model which handles all user related data and logics (loading session data, executing specific checks, etc..) and finally set as class variables those results, so you will end up having:
$this->isLogged ;
$this->isPaying ;
$this->isPlatinumMember ;
etc..
in any of your classes extending from MY_Controller
that makes very easy to check any condition within any of your Controllers.