CakePHP 3.1 admin prefix routing and logging in issue - php

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

Related

REST setup in routes.php is not working when having two words controller names

We are using CakePHP 3.10.*, friendsofcake/crud ^5.0 and friendsofcake/crud-json-api ^0.4.0. Lately we've been having trouble getting requests to the FirmantesExternosController to be handled according to REST conventions. Where, when sending a POST request, cakephp is expected to execute the "add" action of the controller. But instead, it executes the "index" action.
Here is our router scope inside routes.php
Router::scope('/', function (RouteBuilder $routes) {
$routes->setExtensions(['json','xml']);
...(other resources)...
$routes->resources('Firmantes');
$routes->resources('FirmantesExternos');
$routes->connect('/', ['controller' => 'Pages', 'action' => 'display', 'home']);
$routes->connect('/pages/*', ['controller' => 'Pages', 'action' => 'display']);
$routes->fallbacks(DashedRoute::class);
});
We also have in bootstrap.php
Inflector::rules('irregular', [
...(other inflections)...
'firmante' => 'firmantes',
'firmanteexterno' => 'firmantesexternos',
]);
And inside AppController.php
class AppController extends Controller {
use \Crud\Controller\ControllerTrait;
public function initialize()
{
parent::initialize();
$this->loadComponent('RequestHandler');
$this->loadComponent('Crud.Crud', [
'actions' => [
'index' => [
'className' => 'Crud.Index',
'relatedModels' => true
],
'view' => [
'className' => 'Crud.View',
'relatedModels' => true
],
'add' => [
'className' => 'Crud.Add',
'relatedModels' => false
],
'edit' => [
'className' => 'Crud.Edit',
'relatedModels' => false
],
'delete' => [
'className' => 'Crud.Delete',
'relatedModels' => false
]
],
'listeners' => [
'Crud.Api',
'Crud.RelatedModels',
'CrudJsonApi.JsonApi'
]
]);
}
}
The FirmantesExternosController.php
<?php
namespace App\Controller;
use App\Controller\AppController;
class FirmantesExternosController extends AppController
{
}
The FirmantesController.php
<?php
namespace App\Controller;
use App\Controller\AppController;
class FirmantesController extends AppController
{
}
We are using crud component application wide as seen in AppController. Having the FirmantesController working as intended with the REST conventions after puting $routes->resources('firmantes'); in routes.php. But we do the same with FirmantesExternosController and it doesn't work. What are we missing?
THANKS A LOT! To all comments and suggestions.
I solved the problem doing the following:
Make sure to use "case sensitive controller names" in the $routes->resources('...'); lines. In this case $routes->resources('FirmantesExternos'); is the correct format.
In the console inside de cakephp project, run bin/cake routes to figure the route format that cakephp uses. And then make sure to use these in your requests to the api.

CakePHP 3.x using redirectUrl() on diffrent User Roles

I am using the Auth Component to set the redirects on Login and Logout:
$this->loadComponent('Auth', [
'loginRedirect' => [
'controller' => 'Adresses',
'action' => 'index'
],
'logoutRedirect' => [
'controller' => 'Pages',
'action' => 'display',
'home'
],
'authenticate' => [
'Form' => [
'fields' => ['username' => 'email']
]
],
'authorize' => 'Controller',
]);
Now I want the User to get redirect on different pages accordance with their role,which works well so far:
if ($this->Auth->user('role') == 'admin') {
return $this->redirect([
'controller' => 'adresses',
'action' => 'adminindex'
]);
}
} elseif ($this->Auth->user('role') == 'user') {
return $this->redirect([
'controller' => 'adresses',
'action' => 'index'
]);
}
Now I want to redirect the different roles to the requested links.And for that I am using:
return $this->redirect($this->Auth->redirectUrl());
Which works only for request like view and edit.Otherwise It is falling back to the Auth Component redirect , which I do not want.
How can I accomplish that I have my regular Fallback in the Auth Component (App Controller) my Role switcher and also the redirect, when views are requested and the user/admin is not logged in already.
For that i tried:
if(!empty($this->Auth->redirectUrl())){
}
Which doesn't working.Any idea would be appreciated.
$this->Auth->redirectUrl()
is just for Redirecting Users After Login
see http://book.cakephp.org/3.0/en/controllers/components/authentication.html#redirecting-users-after-login
if you need redirect to referer pages , you can use Controller::referer()
see http://api.cakephp.org/3.3/class-Cake.Controller.Controller.html#_referer
you can check logged in users with $this->Auth->user()

Redirect all webpages under webroot to login page in Cakephp

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.

CakePHP - Routing Using 'admin_' Prefix

I am currently using cake's routes config in order to set up admin views, different from that of the non-admin user. I read the routing chapter of the documentation(cake's), and stumbled upon the prefix routing. Which I thought that it is something I need to use, to accomplish what I need. So I started it with setting up the config/core.php as suggested, and uncommented this
Configure::write('Routing.prefixes', array('admin'));
Then, I added a route in the routes.php :
Router::connect('/admin', array('controller' => 'donors', 'action' => 'index', 'admin' => true));
From what I understood, with the above set, I can define a specific action for the admin, names like : admin_index or admin_view, etc. .
So my AppController has a component set like this :
public $components = array(
'DebugKit.Toolbar',
'Session',
'Auth' => array(
'loginRedirect' => array(
'controller' => 'donors',
'action' => 'index'
),
'authError' => 'Access Denied',
'logoutRedirect' => array(
'controller' => 'users',
'action' => 'login'
),
'authorize' => array('Controller')
)
);
So when a non-admin user logs in he should be redirected to 'donors/index', and when the admin logs in I want to redirect him to 'donors/admin_index'.. How can i do this ?
I tried this :
public function beforeFilter(){
if(isset($this->params['admin'])){
$this->layout = 'stafflayout';
$this->Auth->loginRedirect = array(
'controller'=>'donors',
'action'=>'index',
'prefix'=>'admin',
'admin'=>true
);
}
And in the process of testing it out, at first glance I though it worked. but the URL does not change like 'donor/admin_index .. and am still being redirected to donors/index or equivalent, simply to /donors... Why is this not working ?
(seconndary question)Also during the process of testing this out, I changed my the controller and actions of the Auth component LoginRedirect to
'controller'=>'posts'
and
'action'=>'index'
other then 'donors', 'index', and when I logged in, I still got redirected to donors/index.. were it should have redirected me to 'posts/index'
Anyone can help me on these two issues? Primary questions is more important though!
Well the code is fine!
Router::connect('/admin', array('controller' => 'donors',
'action' => 'index', 'admin' => true));
the above will render /donors/index page whenever /admin is written in the url.
Now if you want to add prefix like /donors/admin_index then you have to create one more rule such as:
Router::connect('/donors/admin_index', array('controller' => 'donors',
'action' => 'index', 'admin' => true));
and in beforeFilter function
if(isset($this->params['admin'])){
$this->layout = 'stafflayout';
$this->Auth->loginRedirect = array(
'controller'=>'donors',
'action'=>'admin_index',
'admin'=>true
);
the above code will redirect to /donors/admin_index and routing will render /donors/index page

cakephp logout redirect

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.

Categories