I have a cakephp app that when I logout it add's admin/login ti the url of the logging in screen. Then when I log in again it says missing controler. I already have a redirect to the Auth logout. If I change that will it still logout?
Original login url:
mydomain.com/res/admin
Url after logout
mydomain.com/res/admin/users/login
After I log in to admin:
mydomain.com/res/admin/admin/login
user controller:
function admin_logout() {
$this->redirect($this->Auth->logout());
}
In AppController you can do something like this
public $components = array(
'Session',
'Auth' => array(
'loginRedirect' => array('controller' => 'posts', 'action' => 'index'),
'logoutRedirect' => array('controller' => 'users', 'action' => 'login', 'login'),//redirect url
'authorize' => array('Controller')
)
);
and in UserController
public function logout() {
$this->redirect($this->Auth->logout());
}
this worked for me.
I solved this by putting a logout redirect in the beforefilter.
Related
I'm starting a new app using Cake 3.1 for the first time. I used to use version 2+, but now things have changed and I am encountering some troubles.
I want to have a simple authorization system in my app, so I decide to go with "admin" prefix routing.
I have:
UsersController with login action, 'ArticlesController' with namespace App\Controller\Admin in Controller/Admin/ directory.
In routes.php I have:
Router::prefix('admin', function ($routes) {
$routes->fallbacks('DashedRoute');
});
What goes wrong:
If I have already logged in everything works fine and I have access to my admin actions.
But if I'm not logged in, and will try to access /admin/articles/add I will be redirected to /admin/users/login. And this is totally wrong and I'm obviously get Missing Controller exception.
My question:
What I need to do to fix this and get a proper redirect to login action /users/login and not the prefixed version (/admin/users/login).
AppController:
public function initialize()
{
parent::initialize();
$this->loadComponent('RequestHandler');
$this->loadComponent('Flash');
$this->loadComponent('Auth', [
'loginRedirect' => [
'controller' => 'Pages',
'action' => 'display',
'home',
],
'logoutRedirect' => [
'controller' => 'Pages',
'action' => 'display',
'home'
]
]);
}
public function beforeFilter(Event $event)
{
$this->Auth->allow(['index', 'view', 'display']);
}
Okay. I found the solution – just need to add
'loginAction' => [
'prefix' => false,
'controller' => 'Users',
'action' => 'login',
]
to auth component configuration
Ok, so I have my site set-up in the following way.
The index redirects to the Login page as the entire site is for logged in users only. When a user attempts to view a page they do not have access to they are dumped into the login page with a "You are not authorized to access that location" message.
I want to change this so if a logged in user tried to access a unauthenticated page they get redirected back to the referrer page.
In my individual controllers I have a isAuthorised method that checks the user role and allows or disallows access.
class AppController extends Controller {
public $theme = 'Default';
public function beforeRender(){
$this->set('referer',$this->referer());
$this->set('userData', $this->Auth->user());
}
public $components = array(
'Session',
'Auth' => array(
'loginRedirect' => array(
'controller' => 'users',
'action' => 'login'
),
'logoutRedirect' => array(
'controller' => 'users',
'action' => 'login',
'home'
),
'authorize' => array('Controller')
)
);
public function isAuthorized($user) {
// Admin can access every action
if (isset($user['role']) && $user['role'] === 'admin') {
return true;
}
// Default deny
return false;
}
}
Looking through the documentation I have found unauthorizedRedirect and thought this might be able to do it but I've yet to find a way to implement it. I've tried a couple of things but as yet can't find anything that works properly.
You can add this line in your auth component to redirect the unauthorized users back to the page they came from.
'unauthorizedRedirect' => $this->referer()
Looks something like this:
public $components = array(
'Session',
'Auth' => array(
'loginRedirect' => array(
'controller' => 'users',
'action' => 'login'
),
'logoutRedirect' => array(
'controller' => 'users',
'action' => 'login',
'home'
),
'authorize' => array('Controller'),
'unauthorizedRedirect' => $this->referer()
)
);
public function beforeRender(){
$user = READ USER SESSION
if(!$this->isAuthorized($user)){
WRITE REDIRECT CODE HERE
}
$this->set('referer',$this->referer());
$this->set('userData', $this->Auth->user());
}
I am using cakephp 2.4.5. I would like to redirect all users who have not logged in to a login page. I basically followed the instructions available here.
In summary, the important part is the following code to AppController.php
public $components = array('Session',
'Auth' => array(
'loginRedirect' => array('controller' => 'users', 'action' => 'index'),
'logoutRedirect' => array('controller' => 'users', 'action' => 'login'),
'authError' => 'You must be logged in to view this page.',
'loginError' => 'Invalid Username or Password entered, please try again.'
));
Any websites with this URL format http://localhost/cakephp245/controllers/XXX will be re-directed to the login page. However, websites that are located inside app/webroot with URL that looks like this http://localhost/cakephp245/app/webroot/XXX will not be re-directed to the login page.
How can I force websites located inside app/webroot folder to be re-directed to the login page?
Thank you very much.
Below are the steps that can help to resolve the issues :-
1) Read the documentation how to load the auth componenet in appController
https://book.cakephp.org/3.0/en/controllers/components/authentication.html
Code should be like the below code
$this->loadComponent('Auth', [
'loginAction' => [
'controller' => 'Users',
'action' => 'login',
'plugin' => null
],
//'authorize' => ['Controller'],
'loginRedirect' => [
'controller' => 'Users',
'action' => 'dashboard'
],
'logoutRedirect' => [
'controller' => 'Users',
'action' => 'login',
],
'authenticate' => [
'Form' => [
'fields' => ['username' => 'email', 'password' => 'password']
]
],
'unauthorizedRedirect' => false,
'authError' => 'Did you really think you are allowed to see that?',
'storage' => 'Session'
]);
2) Add below code to beforeFilter() of usersController
$this->Auth->allow(['login','logout','register']); // these function will be pulic access
3) Here is the login function put it in UserController
public function login()
{
$this->viewBuilder()->layout('adminlogin'); // set the admin login layout
$user = $this->Users->newEntity();
$this->set('user', $user);
if ($this->request->is('post')) {
$user = $this->Auth->identify();
if ($user){
$this->Auth->setUser($user);
return $this->redirect($this->Auth->redirectUrl());
}else{
$this->Flash->error(__('Invalid username or password, try again'));
}
}
}
Add this function to the AppController.
public function beforeFilter() {
$this->Auth->deny();
$this->Auth->allow('login');
}
This way, the only action allowed before login is login itself.
Still, this won't make images or scripts or css unavailable, if that's what you're aiming for.
Though I'm not completely certain, I believe there is no way to deny someone access to this type of resources.
On localhost i have no problem at all. i can login access all sites and go through the process of the site without a problem.
Now when i put it remotely i get logged out as soon as i change page (aka i am being redirected to my login view no matter what link i press)
My AppController loos like this:
<?php
App::uses('Controller', 'Controller');
class AppController extends Controller {
public $components = array(
'Acl',
'Auth' => array(
'authorize' => array(
'Actions' => array('actionPath' => 'controllers')
)
),
'Session'
);
public $uses = array
(
'Category'
);
public $helpers = array('Html', 'Form', 'Session');
public function beforeFilter() {
$this->Auth->allow('*');
//Configure AuthComponent
$this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
$this->Auth->logoutRedirect = array('controller' => 'users', 'action' => 'login');
$this->Auth->loginRedirect = array('controller' => 'home', 'action' => 'index');
$this->set('menu_categories', $this->Category->find('all'));
}
}
Please tell me if you need more information (also if you wish to try this issue go to my page (my domain
log in as test password test123
I want to let Auth give access to login(), logout() and add() action of my users controller, but it doesn't matter if I use $this->Auth->allow('logout'); or not I get the message: You are not authorized to access that location. login() and add() work fine though.
This is my AppContoller.php:
class AppController extends Controller {
public $components = array(
'Auth' => array(
'authenticate' => array(
'Form' => array(
'userModel' => 'User',
'fields' => array(
'username' => 'email', 'password' => 'password')
)
),
'loginRedirect' => array('controller' => 'users', 'action' => 'index'),
'logoutRedirect' => array('controller' => 'pages', 'action' => 'display', 'landing')
), 'Session'
);
public function beforeFilter() {
$this->Auth->allow('add', 'login');
}
}
And this is the relevant part of my UsersController.php:
public $helpers = array('Html', 'Form', 'Session');
public $components = array('Session');
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('logout');
}
public function logout() {
$this->set('title_for_layout', 'Logout');
$this->redirect($this->Auth->logout());
}
Does anyone see the problem here? I appreciate your help.
It seems you are accessing to logout action without problems but the logout redirection destroys your session and redirects you to a page view.
It seems you don't have access to the page without being logged. (you can try it accessing to the URL without being logged)
Add the beforeFilter function at your PagesController:
public function beforeFilter(){
parent::beforeFilter();
$this->Auth->allow();
}
PagesController comes by default with CakePHP 2.2, if you don't have it, just copy and paste any other controller and add this function deleting all the rest.
EDITED:
If the PagesController was already there, just add the beforeFilter function.