Avoid CakePHP's Auth component to display authentication error messages
I would like to get rid of Auth component error messages, specially the authError message that comes whenever I try to access a non-allowed action.
Just to be sure, I double check that there is no $this->Session->flash()
call anywhere in the layout. Besides, setting an empty value does not work, as the component has a default message value.
I am using the Auth component with the following configuration in AppController class:
class AppController extends 开发者_如何学PythonController {
var $components = array(
'Auth' => array(
'userModel' => 'WebUser',
'loginAction' => '/login',
'loginRedirect' => '/',
'logoutRedirect' => '/login',
'autoRedirect' => false,
),
'Session',
...
...
}
For login and logout redirections I have setup two routes:
Router::connect('/', array('controller' => 'posts', 'action' => 'index'));
Router::connect('/login', array('controller' => 'web_users', 'action' => 'login'));
The login action within WebUser controller is almost empty; I only change the default layout:
function login() {
$this->layout = 'login';
$this->set('title_for_layout', 'Sign in');
}
Finally, I have a very simple login.ctp layout file:
<html>
<head>
...
</head>
<body>
...
<?php echo $content_for_layout; ?>
...
</body>
</html>
When I access http://example.com/login
there is no problem, no messages, just the login form. However I get the default authError message when requesting any other action, just after the Auth component redirects to the login action. Two questions arise:
Why is the Auth component displaying flash messages when there is no(see update 2 below)$this->Session->flash()
call anywhere?- How can I setup an empty/null value in authError attribute?
Thanks!
UPDATE
I came up with a really ugly solution: I created an element login_error.ctp and assigned to the flashElement attribute in Auth component initialization:
class AppController extends Controller {
var $components = array(
'Auth' => array(
'flashElement' => 'login_error',
...
...
}
In login_error.ctp I just compare with the authError default message:
<?php if ( $message !== 'You are not authorized to access that location.' ): ?>
<div id="flashMessage" class="message"><?php echo $message; ?></div>
<?php endif; ?>
It works, but I hate it!
UPDATE 2
Thanks to dogmatic69 answer I forced myself to check everything again. I finally found where the call to $this->Session->flash()
was being made. It was on a little view element that I had wrote before. It had nothing to do with login/logout stuff so I did not pay attention to that file.
UPDATE 3
Thanks to SpawnCxy answer as well. Copying the Auth component and making custom modifications is a better approach than string comparison.
just remove $this->Session->flash('auth')
from your view/layout.
http://book.cakephp.org/view/1467/flash
In CakePHP 2.1 in my AppController, I am using this to override my "auth" flash messages. Here is my $components:
public $components = array(
'Acl',
'Auth' => array(
'flash' => array(
'element' => 'info',
'key' => 'auth',
'params' => array()
),
'authorize' => array(
'Actions' => array('actionPath' => 'controllers')
),
),
'Session',
);
I am uncertain about if you can do this in previous versions of Cake. Also, you can do:
function beforeFilter() {
//Configure AuthComponent.
$this->Auth->authorize = 'actions';
$this->Auth->actionPath = 'controllers/';
$this->Auth->loginAction = array('controller' => 'users', 'action' => 'login', 'plugin' => NULL);
$this->Auth->loginRedirect = array('controller' => 'users', 'action' => 'login', 'plugin' => NULL);
$this->Auth->logoutRedirect = array('controller' => 'users', 'action' => 'login', 'plugin' => NULL);
$this->Auth->authError = __('You must be logged in to view this page.');
$this->Auth->loginError = __('Invalid Username or Password entered, please try again.');
$this->Auth->flash = array(
'element' => 'info',
'key' => 'auth',
'params' => array()
);
}
That works too! Nice!
There's another way to make the Auth component more personalized.You can copy
/cake/libs/controller/components/auth.php
to
/app/controllers/components/auth.php
and edit the __setDefaults
function in the new copy.You can specify your own auth error message by change the value of key authError
in $defaults
.Set it an empty string if you want to show nothing.
I just tested this in Cake 2.x and it worked. Put this in your Controller's beforeFilter()
function:
$this->Session->delete('Message.auth');
I had a similar scenario.
When a user is logged in, '/' routes to a dashboard action in a controller. When a user is not logged in, however, I wanted the user to be able to request either mydomain.com or mydomain.com/users/login without getting an authError message.
If the user requested any other page, however, I wanted the “not authorized” authError message to display as it normally would.
Here's my solution: in the beforeFilter in the AppController
if($this->request->here == '/' && !$this->Auth->loggedIn()){
$this->Auth->allow('dashboard'); //temporarily allow the dashboard action
$this->redirect(array('controller' => 'users', 'action' => 'login')); //manually redirect to login screen
}
Because of the way routes work, if the user requests '/' they will not receive an auth error. However, if they request /controller_name/dashboard, they will receive an auth error because $this->Auth->allow('dashboard') only fires if they request '/'.
I practice another better way than Young's Answer. In AppController please set following code :
function beforeFilter(){
... ... ...
//set auth message custom id, if required.
$this->Auth->flash['key'] = 'YOUR-ID-HERE';
//set auth message custom attributes e.g. class etc., if required
$this->Auth->flash['params']=array('class'=>'YOUR-CLASS-HERE');
//set auth message custom element path, if required
$this->Auth->flash['element'] = 'YOUR-ELEMENT-PATH-HERE';
... ... ...
}
I hope it will be better than customization Core Libraries for a simple work.
I was with a similar issue, but I'm using CakePHP 3.4. I solved editing config/routes.php
:
//$routes->connect('/', ['controller' => 'Pages', 'action' => 'display', 'home']);
$routes->redirect('/', ['controller' => 'Users', 'action' => 'login']);
精彩评论