zend validate user for a specific controller? - php

HI i would like to know how to validate a users for a specific controller, so that we can check that a specific users is authenticate before accessing resources of a controller?

you should take a look at Zend_Auth and Zend_Acl Component.
Zend_Auth is responsible for assigning and managing authentication of the user.
Zend_Acl is responsible for managing different permissions and roles for different resources.
here is the tutorial explaining how you can implement Zend_Auth.
http://akrabat.com/zend-auth-tutorial/
and the below tutorial explains about Zend_Auth/Zend_Acl
http://devzone.zend.com/844/zend_acl-zend_auth-example-scenario/

Lets says for a specific controller in controller folder we have CashoutController. Before a user accessing this controller we will authenticate the users as below with make use of custom library.
<?php
class CashoutController extends Zc_Controller_Action_User
{
public function init()
{
/* Initialize action controller here */
parent::init();
}
// rest code goes here
}
now we defined new library name Zc
<?php
class Zc_Controller_Action_User extends Zc_Controller_Action
{
public function init()
{
parent::init();
$this->validateAccess();
}
private function validateAccess()
{
$auth = Zend_Auth::getInstance();
if (is_null($auth->getIdentity())) {
$this->_helper->redirector('index', 'index');
}
}
}
where we define controller action library as
<?php
class Birdtoldme_Controller_Action extends Zend_Controller_Action
{
}
hope this is has been an informative for you.

Related

CodeIgniter : Using both core classes and extended classes ?

I'm currently working on CI for my website, and i'm having some trouble about extending Controller_CI.
I have one controller that deals with login/signin actions, which doesn't need authentication, and others controllers that check if a user session exists before loading content.
For that purpose, I created MY_Controller class and add authentication code in the constructor.
Then I made all my controller extend MY_Controller, except the first one that still extends Controller_CI
My question is : Is it the right way to deals with authentication ? Is it still possible to use Controller_CI even if it's extended ?
I found another pattern :
http://philsturgeon.co.uk/blog/2010/02/CodeIgniter-Base-Classes-Keeping-it-DRY
I guess it's better, but still, I don't understand why not using the first solution.
Thanks
Extending controller class for that purpose will work, but this solution is not much flexible. I would rather create a library that handles authentication, and run it from a controller when it is desired. Please read http://ellislab.com/codeigniter/user-guide/general/creating_libraries.html for details about creating custom libraries in CI.
Please remember you can only extend the CI_Controller with MY_Controller only once. In that aspects it's not a good idea. Suppose you want to implement another feature (e.g. a piece of code that makes a specific entry in the log) for some controllers, but not necessarily the controllers that need authentication you cannot make another MY_Controller.
Using a library is a better thing.
I'm using the flexi auth library on a big CI site. On every controller that requires authentication I just add the following:
public function __construct() {
parent::__construct();
$this->load->library('flexi_auth');
if (!$this->flexi_auth->is_logged_in())
redirect('auth/login');
}
I think a combination of what Phil Sturgeon suggests in that blog post and using a library would be best. So I would create a core controller (by that I mean a controller you place into application/core that extends CI_Controller) called MY_Controller which will look something like this
class MY_Controller extends CI_Controller
{
function __construct()
{
parent::__construct();
}
//Any other functions you want
}
Then judging by your question you currently have controllers that fit into two categories
Controllers that do require a logged in user before they do
anything
Controllers that don't require a logged in user before they do anything
So I would then create another controller in the /application/core directory that extends MY_Controller but in its constructor it checks to see if the user is logged in
class Auth_Controller extends My_Controller
{
function __construct()
{
parent::__construct();
//Check to see if the user is logged in
$this->load->library('authentication');
if(!$this->authentication->user_logged_in())
{
redirect('/login');
}
}
//Any other functions you want
}
Now when you create you controller you can choose which one of the core controllers you want to extend. If its a controller than doesn't require a logged in user you can extend MY_Controller but if it does required a logged in user you can extend Auth_Controller. That way it means you only need to do the user login check once in your code.
Like others have said if may be a good idea to place any authentication code into a library as that's a better place to put it than in a controller.
Summary
So to summarise by having all of your controllers extend core controllers rather than CI_Controller it should cut down on code repetition.
I also currently working on a CI project and had the same issue. I have came up with a different solution to deal with the authentication.
I extended the core controller as bellow,
class MY_Controller extends CI_Controller
{
public $data = array();
public $calledClass ;
public $calledMethod ;
public function __construct()
{
parent::__construct();
$authException['authentication']['login'] = true;
$authException['authentication']['logout'] = true;
$authException['welcome']['index'] = true;
$this->load->library("router");
$this->calledClass = $this->router->fetch_class();
$this->calledMethod = $this->router->fetch_method();
if(!#$authentication[$this->calledClass][$authentication->calledMethod] && !Auth::isUserLoggedIn())
{
# IS_AJAX is a contant defined in the contants.php
# define('IS_AJAX', isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest');
if(IS_AJAX)
{
# if this is an AJAX call, it sets a value in the header ,
# which can be captured in the AJAX response
# to redirect the user to the login page.
$this->output->set_header("auth-him:1");
exit;
}
else
{
redirect("authentication/login");
}
}
}
}
Hope the code above is clear and this helps.
To extend core controller more than one time, If you still need to use 2 controllers to handle authentication, I have followed this method
https://stackoverflow.com/a/22125436/567854
Hope this also helps :)

Method in one controller calling a method in another controller, using MVC

so i have a user controller, that has methods to update profile, etc. In the system i am developing the user would need to post articles, etc. So i am confused with the design of the system. The main logic of creating articles would be housed under the article_model. But how should i call the methods?
I can create a function in the user controller that calls on the article model to create article?
I can call a method in the user controller and create an article controller and the user controller calls the method on the article controller, which in turns call the model for the main logic.
Or just directly call on a article controller that connects to the article model.
I personally feel i need to have a user controller into this system, as logically speaking a user creates article. So which design is perfect in terms of logic and best practices.
You can load multiple models in a controller, you’re not just restricting to the model in the same domain as the controller. So if you need to interface with articles in the users controller, then just load the articles model. As deceze says, you shouldn’t call other controllers in one controller; that definitely goes against MVC conventions.
In your case, any interaction with an article should be in the articles controller though, accessible at a URL like /articles/add.
I actually use codeigniter and they do it this way. If you want to post an article from your user or profile controller you can just make an instance or load your model.
class ProfileController extends BaseController {
public function __construct()
{
$this->load->model('article_model');
}
public function index(){
$this->article_model->post();
}
}
don't call a controller from another controller
you can add link to any view called with the profile that reefers to add article
if you have to call the controller from another you may have a look at codeigniter hmvc
HMVC: an Introduction and Application
Try to use this extension HMVC for CI. It's allow to call controller methods in another controllers. Something like this:
class Dashboard extends MX_Controller{
public $autoload = array();
public function __construct()
{
parent::__construct();
}
public function index()
{
$params = 'some_params';
$data['some_data'] = Modules::run('another_controller/method', $params);
}
}
Where another_controller - simple CI controller, what expand MX_Controller.

Getting user data

There are two parts to this application I've been building. There's the website which is powered by the CMS and there's the CMS (wrestling manager) that goes with it. With the two controllers I created called frontend and backend I use those accordingly. The frontend controller is responsible for the code that needs to be ran across all controllers on the website. The backend controller is responsible for the code that needs to be ran across all controllers on the CMS.
I'm looking for the ideal way to work with the user data after the user successfully logs in again gets directed to the dashboard which is extended by the backend controller. I've heard different solutions for example a hook. That's just one I've heard.
Inheritance is your friend here
You would simply create a master controller(front-controller) that extends CI_Controller
You might consider doing a SPA application, if so there are many great frameworks to help you achieve this, quite a popular one is angular.js
some more useful reading on the subject...
class MY_Controller extends CI_Controller
{
protected $currentUser;
protected $template;
public function __construct()
{
//You talked about hooks
//this constructor is the same as saying
//post_controller_constructor
$this->template = 'master/default';
}
//Ok so what functions need to be run
//throughout the application
//run them once here, keeping our app DRY
protected function isAjax()
{
return ($this->input->is_ajax_request())
? true
: show_error('Invalid Request!');
}
protected function isLoggedIN()
{
//load your auth library maybe here
$this->load->library('auth');
//check you have a "current logged In user"
//expect object or null/false
$this->currentUser = $this->auth->getLoggedInUser();
return ($this->currentUser) ?: false;
}
}
class Frontend_Controller extends MY_Controller
{
public function __construct()
{
parent::__construct();
}
public function testFirst()
{
//maybe you just need to test for ajax request here
//inheritance from parent
$this->isAjax();
}
public function testSecond()
{
//maybe you DO need a user logged in here
//inheritance from parent
$this->isAjax();
//or yet again, abstract this to the parent level
if(!$this->currentUser || is_null($this->currentUser))
{
//handle errors on frontend
return $this->output->set_status_header(401); //un-authorized
}
}
}

Is there a way to have multiple controllers for a symfony 1.4 module?

I have a situation where I have a base controller (a base actions.php file) in Symfony 1.4. I want to create another controller, for the same module, that extends that base controller.
I need to extend that base controller because I want to customize the behavior of certain visitors, that are identified based on an ID in the URL.
Any hints?
Another controller class for the same module, I think it's impossible in symfony.
I guess the easiest solution for you is to create another method in the same class, and then invoque it from the base one.
By Example: actions.class.php:
public function executeBaseAction(sfWebRequest $request) {
.. if($user....) then return $this->executeCustomAction($request);
}
public function executeCustomAction(sfWebRequest $request) {
// $this->setTemplate('anotherTemplate?');
}
Actually you can add another controller class for the same module.
You could include several files in your action directory in this way:
In action1Action.class.php
class action1Action extends sfAction
{
public function execute($request) {
//Your code here
}
}
This will use template action1Success.php
In action2Action.class.php
class action2Action extends sfAction
{
public function execute($request) {
//Your code here
}
}
This will use template action2Success.php

How to make user object available across pages in CodeIgniter?

I'm fairly new to CodeIgniter and I'm using Ion Auth for user authorization. With the Ion Auth library, you get a user object like:
$user = $this->ion_auth->get_user();
echo $user->email;
If a user is logged in, I want the $user object to be available on any of the pages (in any of the controllers). How can I do this? (I'm using CodeIgniter 2)
This blog post of mine goes into a lot of detail in specifically using Ion_Auth to allow your entire application (including views) to access your current user's information.
The short version... (specifically for the topic at hand)
Adding this to your MY_Controller.php file
class User_Controller extends CI_Controller {
protected $the_user;
public function __construct() {
parent::__construct();
if($this->ion_auth->logged_in()) {
$data->the_user = $this->ion_auth->get_user();
$this->the_user = $data->the_user;
$this->load->vars($data);
}
else {
redirect('/');
}
}
}
Then in your application just create your controller like this
class App_Controller extends User_Controller {
public function __construct() {
parent::__construct();
}
function index() {
//do stuff
}
}
Then not only in your controller will you have access to $this->the_user but you will also have $the_user loaded into every view with $this->load->vars()
Normally you'd cache something like this in the session, however I've moved away from that in most of my CI apps.
An example: you log the user in (caching the user data) and then they go to update their email on their profile page. You now have to reload you cache. Many other things could drive this reload. Usually the most I cache any more is the ID, then I do what you're doing and get the user's data on any page I need it.
One thing I found that helps is to have base controllers. For example I have a RegisteredUserController. Any controller whose actions all require the user to be logged in extend this. That way I can keep the logged in check and things like get the user data in one spot (in the constructor). For example:
class RegisteredUserController extends CI_Controller {
var $user;
function __construct() {
parent::__construct();
$this->user = $this->ion_auth->get_user();
}
}
Then any controller that extends RegisteredUserController instead of just controller can get to the user with $this->user. Following this pattern would get it on every page (that extends the controller) without resorting to caching.

Categories