So a change was made to Controller::redirect and now it fires AFTER your controller action is called. So if you're wanting to redirect someone (that's not logged in for example) before logic is fired that is no longer possible. Does anyone know how to simulate the old 2.X behavior where a call to Controller::redirect would immediately stop everything and redirected?
The key is to return the $this->redirect() call, that will return a response object immediately from the controller that will make the Dispatcher understand that you want to terminante the request immediately:
return $this->redirect($url);
The redirect can be done from the controller action itself or any of the callbacks in the controller (beforeFilter, beforeRender, afterFilter ...). Returning the redirect value is also allowed from any of the component callbacks.
There are three possible ways to redirect user if he not logged in. I did it one of my app. First is using beforeFilter() of a controller. You could use like
public function beforeFilter(){
parent::beforeFilter();
if(empty($this->logged_in)){
//your redirect code or your logic
}
}
It executes at very first time when your controller action is being called.
Second you can create a class's constructor function. It executes also at very first.
public function __construct( $request = null, $response = null ) {
parent::__construct( $request = null, $response = null );
//Your redirect code if user not logged in
}
You can write your code in AppController beforeFilter(); But if you only want to prevent non logged in users to access some function, you should use Auth component allow function. Syntax is
$this->Auth->allow(array('action_name_1','action_name2'));
Paste this allow function in beforeFilter function. By using above tricks you can prevent user to access your logic if he / she not logged in.
I just had the same issue. And I ended up with good old header() function along with die()
header('Location: http://example.com/whatever');
die;
Related
Controller in my default route gets executed after I logout. For loginG out I am just calling a server route using $http.post. As the thing is async, execution continues to go to my default route '\' but I don't want controller of my default route to execute until logout is complete. How can I create a link between logout and my controller? I know I can use promise to wait for Logout but this would be only in the function where I am calling logout. How can I wait in my controller for logout to finish?
Will appreciate any help.
Thanks.
Promises let you add a handler to their completion that's chainable:
// inside your controller action causing the log out:
$http.post("/logout").done(function(result){
// here you're logged out, the promise has its value
$location.href = "/"; // change route
});
Note: you can also wait in your router, but I assume from your question you'd like to avoid that.
Note2: I'd extract membership into a service.
I can't find any example of how to use FriendsOfCake's TokenAuthenticate plugin. I want to know if I have to create the token myself or if it creates it automatically, and also what would be the code inside UsersController::login() function.
You need to create the token yourself. As well, the login() action is the same as any other login action would be.
I'm working on a auth based application where the user must be logged to access to a certain routes of the website. I haven't found documentation on how to accomplish this so I worked on a idea on how to solve it.
This is my function to know if a user is logged or not:
App.filterAuth = function(navigateTo) {
navigateTo = typeof navigateTo !== 'undefined' ? navigateTo : '#';
if (App.logged == false) {
App.vent.trigger('navigate', navigateTo);
}
};
My idea is that when a user is logged sets the App.logged = true. Then, when my router tries to execute a concrete router I can just call App.filterAuth(). This actually works and doing some debugging I see that everything is triggered corrected.
The problem? For example I execute this on a protected route that loads a feed of images for a user. When App.filterAuth() is executed I see that it tries to navigate to # but the execution of this feed view isn't stopped and also the view associated to my # route is not triggered.
Any idea on how I can improve this function that makes it work correctly?
Thanks in advance!
This might not be an answer to question directly, but there is a backbone plugin which can help you with what you try to do: https://github.com/boazsender/backbone.routefilter
You can specify additional methods, which will be triggered before / after route code is processed. If you return false from before callback, router code won't be evaluated: https://github.com/boazsender/backbone.routefilter#returning-false-from-within-a-before-filter
So, you could create before filter, which could check, if route should be secured. If it is secured and user is not authenticated, you just return false and router code is not used.
I have a strange problem in my app. I have a form with some data to edit, when I am trying to save the data, strange things happens.
If I put die('test'); at the end of beforeFilter(), I see "test" on my screen, but if I put it on the beginning of my action, I am redirected to the login page.
It's happening only if I pass some specyfic data
$this->data['Movie']['title'])
if I pass something else
$this->data['Movie']['genere']
everything works fine.
How can I debug it? What is happening between beforFilter and action?
If you Auth component is active then check that in your beforeFilter() function that you allowed the action for that user.
For example:
function beforeFilter() {
$this->Auth->allow( array('add', 'edit', ) ); // for example
}
Within your allow() method include the name of the desired method.
I got layout, nothing special, three columns, just to learn CakePHP. In documentation I found nothing about this case.
I got some statistics in sidebars, si I send them to layout file (default.ctp) cause they are displayed on every page.
I build (thanks to one user here) a component:
class SidebarComponent extends object {
function startup(&$controller) {
$this->controller = $controller; // Stores reference Controller in the component
}
function count_articles() {
$articles = ClassRegistry::init('Articles')->count_articles();
$this->controller->set(compact('articles'));
}
}
Everything is working perfectly. I got question about my technique. I needed to load component method in controller by putting:
$this->Sidebar->count_articles();
So I decided to make it a bit shorter, cause I will have to put it in every controller. So, I created new component's function:
function sidebars($userid) {
return array(
$this->top_articles(),
$this->random_article()
);
}
And I initialize it in controller that way:
$this->Sidebar->sidebars();
Everything is working correctly, I need only advice/feedback if it's good way I do this :)
Thanks for your time.
you don't need to call it explicitly in every controller. component's startup() method is called automatically before every action in the controller that is using your component.
so you can use startup() to get and set your data for views, and if you need some initialization before (like getting reference to controller), put it in component's initialize() method.
If you have sidebars with the same things in them, also sounds like a case for elements as well