I have a problem here. I created a cakePHP application using the Bake feature of cakePHP. I baked my Model, my Controller and my views (with default index, add, edit, and view actions). I created a small table called users in my database which contains only three fields (id int auto_increment primary key, username varchar(15), password charr(40)). The problem that I'm having is that when I use the Auth component, I get stuck on the logging page forever (until I take it out). I have tried almost EVERYTHING in my functions login() and beforeFilter() with no success. Any idea please?
I use the Auth component like so in my Users Controller:
var $components = array('Auth');
I have tried this in my function beforeFilter(), but it does not work:
function beforeFilter() {
$this->Auth->autoRedirect = false;
parent::beforeFilter();
}
I have even tried to redirect right in my function login() like so:
function login() {
$this->redirect($this->Auth->redirect());
}
But when I do this I get error 310: TOO MANY REDIRECTS.
I cannot go to my index, or add, or view page. Help please?
In the code you provided, you don't seem to do anything to make the 'login' action reachable if you are not logged in yet.
function beforeFilter()
{
parent :: beforeFilter();
$this->Auth->allow('login');
}
If you don't do that, the login page is protected, making you redirected to... the login page, making you redirected to... the login page, making you redirected to... the login page, making you redirected to... the login page ;-)
This piece of code has you caught in an endless loop, because it keeps redirecting you back to the login page:
function login() {
$this->redirect($this->Auth->redirect());
}
Read up here on list of Auth component variables. Specifically the loginRedirect part. You need to put that in into your beforeFilter function:
function beforeFilter() {
parent::beforeFilter();
$this->Auth->loginRedirect = array('controller' => 'users', 'action' => 'index');
}
Related
Edit: Version: 2.5.7
I'm currently trying to setup role based authentication with CakePHP. So far I've managed to get authentication to work ok, where controller access redirects to a login screen when not authenticated, and permits access when I am authenticated..
My problem comes when I want certain 'admin' level access to certain action methods, (prefixed with admin_) yet denies them for regular logins.
If I uncomment $this->Auth->authorize in the beforeFilter, my authentication works fine..Comment it in, and I can't log in.
AppController
public function isAuthorized() {
if (!empty($this->params['action']) && (strpos($this->params['action'],'admin_') !== false) ) {
if ($this->Auth->user('admin')) {
return true;
}
}
return false;
}
public function beforeFilter()
{
$this->Auth->authorize = 'controller';
$this->Auth->deny(); //deny everythng
}
My Dashboard controller is the first screen after successful login. It's before filter just looks like this. Do I need to put a parent:: isAuthorized call somewhere? Or when exactly is the isAuthorized call made? I can tell it is firing, but just not sure why I get kicked back to the login screen when I implement it.
Dashboard Controller.
public function beforeFilter()
{
parent::beforeFilter();
}
Kind of found a solution (of sorts)
Cookbook tells you to do this: http://book.cakephp.org/2.0/en/tutorials-and-examples/blog-auth-example/auth.html
(See under PostController). I whitelist the actions I want regular logged in users to see, and the parent isAuthorized handles the admin scenarios.
Dashboard Controller
public function isAuthorized($user) {
$actions = array("stats","index");
if (in_array($this->action, $actions)) {
return true;
}
return parent::isAuthorized($user);
}
Problem with this approach is that its pretty painful to have each of my controllers having this sort of white list code in each one. Feels ugly to me.
im using cake php 2.4 my problem is sometimes after session idle, or logout in other tab the ajax request doesn't work because the user is already logged out.
my question is how i can verify that to redirect the user to the login page.
my function that im using to filter requests is used on my userscontroller class
//class UsersController
public function beforefilter(){
parent::beforeFilter();
// Allow users to logout.
$this->Auth->allow('logout');
}
thank you
if (!$this->Session->read('Auth.User')) {
// redirect here
}
I have created a CakePHP app where I have created a UsersController, which handles all about users.
When I try to browse www.mydomain.com, if I am logged in, it let's me see the index (app/View/Pages/home.ctp). Else, it redirects me to mydomain.com/users/login and persists to log in.
I have tried looking at AppController.php, PagesController.php or app/Config/core.php and app/Config/routes.php, but did not find anything. My UsersController.php, also, is not responsible for that, I think.
I do not remember and I cannot find how to disable this. Which file should be responsible for that?
EDIT:my CakePHP version is 2.3.
Generally you can make specific actions public using the auth components allow() method.
Making pages public may require a little more work in case you'd want to make only specific pages public, since the PagesController handles all pages in a single action (display()). If that is the case, then you could utilize request->params['pass'][0] which will hold the page name, test this against a list of allowed pages, and then allow the display action using Auth::allow.
Example, in the PagesController:
public function beforeFilter()
{
parent::beforeFilter();
$allowedPages = array('home', 'foo', 'bar');
if(isset($this->request->params['pass'][0]) &&
in_array($this->request->params['pass'][0], $allowedPages))
{
$this->Auth->allow('display');
}
}
This would allow the pages home, foo and bar to be viewed without being logged in.
If you'd wanted to make all pages public, then you could simply use Auth::allow without any conditions, ie:
public function beforeFilter()
{
parent::beforeFilter();
$this->Auth->allow('display');
}
I have my home screen with Login Form and Registration button at the following location -
http://localhost/myproject/user/login
When user clicks on Register button, the page is re-directed to -
http://localhost/myproject/user/register
where I have Login Form on the top of the page and Registration Form at the bottom. Now when I fill the login form and submit, if the login fails, user is redirected to
http://localhost/myproject/user/login
instead, I want the user to be redirected to
http://localhost/myproject/user/register
How can I achieve this behavior?
I would do something in your Users_Controllers like so...
NOTE: I have not tried it and I am not sure it works... I can repost later after trying this...
First you need to turn Auto Redirect to False
class UsersController extends AppController{
//...
function beforeFilter(){
parent::beforeFilter();
$this->Auth->autoRedirect = FALSE;
}
function login(){
if( !(empty($this->data)) && $this->Auth->user() ){
//...
}else{
//If useR didnt/cant login redirect to register
$this->redirect(array('controller' => 'users', 'action' => 'register'));
// Or if you have routes setup for /register
$this->redirect('/register');
}
}
Hopefully this helps you out. If not I will try some things later and repost
}
If you add code examples, we might be able to better help you.
It sounds like you have one of the two issues:
You have forms or submit buttons with the same ID's or names.
Your forms are posting to the same place.
When the login fails, are you really redirected to /user/login ? Or is the login form action url always pointing to the /user/login page, meaning that if the login fails, you just stay on this page because you are already on it when you check the credential ?
If I'm right, you could obtain what you want by checking the referer in the /user/login action when the login fails and in this case redirect to /user/register if the referer is /user/register.
Turn of autoRedirect in beforeFilter and redirect manually
function beforeFilter()
{
parent::beforeFilter();
$this->Auth->autoRedirect = false;
}
function login()
{
if ($this->RequestHandler->isPost()
{
if ($this->Auth->user()
{
$this->redirect($this->Auth->redirect());
}
else
{
$this->redirect('/users/register');
}
}
// ...
}
I implemented security according to this tutorial:
http://book.cakephp.org/view/1543/Simple-Acl-controlled-Application
What I want it to do is if a user issues a request and isn't logged in, they are presented with the login page and then redirected back to their original request.
I think I need to add code in app_controller.php (the top level controller) to save the initial request as maybe a session variable, and then add a line at the end of this function in the users controller to redirect to the saved value:
function login() {
if ($this->Session->read('Auth.User')) {
$this->Session->setFlash('You are logged in!');
// redirect to referrer here
}
}
Am I on the right track here?
you could do a quick search... Take user back to previous page after logging in?
So from dogmatic's linked thread, it looks like all I needed to do is replace this line from the tutorial:
$this->Auth->loginRedirect = array('controller' => 'alerts', 'action' => 'index');
with this:
$this->Auth->loginRedirect = array('controller' => 'alerts', 'action' => 'home');
I presume you've spent enough time with CakePHP to do steps below. Here is the solution;
Add the Auth and Session components to AppController's components (if you
haven't done). From now on all of your controllers able to use of
Auth and Session functions.
Override the beforeFilter() function of the UsersController (or similar controller
to manage user actions) with that one-line-of-code;
$this->Auth->loginRedirect = $this->Session->read("Auth.loginRedirect");This
code should be placed into function since PHP doesn't support function calls into
variable assingment.
After that, to prevent mistaken redirection to already redirected pages, also add that line to the
UsersController's beforeFilter() function;
$this->Session->write('Auth.loginRedirect', "/");
The above code is not required if you sure that done step 4 for every controller.
Override the beforeFilter() function of
the controller that you wanted to get back there after login with
that one-line-of-code;
$this->Session->write('Auth.loginRedirect', Router::url(null,
true));.What this code does is simply writing the fullbase of
controller/action[/param1...] URL (be careful with the parameters
btw) to the Session with Auth.loginRedirect name.
PS: Read jocull's comment to find out why I didn't use the $this->here.