Cakephp 3 - public function add doesn't work with isAuthorized - cakephp

I have a little problem with the isAuthorized function.
When I use the public function add, isAuthorized doesn't recognize the action request. I changed the name to 'addv' and now it's working. So why? Why can't I use the word 'add'? I used it twice on another project and I used it once on my current project.
Thanks you for you help !
<?php
namespace App\Controller;
use App\Controller\AppController;
use Cake\Event\Event;
use Cake\Validation\Validator;
class VideosController extends AppController{
public function isAuthorized($user){
if(in_array($this->request->action, ['addv'])){
die();
if($user){
return true;
}
}
return parent::isAuthorized($user);
}
public function addv($idc= null,$idg = null){
debug($idc);
debug($this->request->action);
}
}
?>
AppController
class AppController extends Controller {
public function initialize() {
$this->loadComponent('Flash');
$this->loadComponent('Auth', [
'authorize' => ['Controller'],
'loginRedirect' => [
'controller' => 'Pages',
'action' => 'display',
'home'
],
'logoutRedirect' => [
'controller' => 'Pages',
'action' => 'display',
'home'
]
]);
$this->loadComponent('RequestHandler');
$this->set('info_session', $this->Auth->user());
}
public function beforeFilter(Event $event){
$this->Auth->allow(['register']);
$this->Auth->allow(['display']);
$this->Auth->allow(['controller' => 'Users', 'action' => 'add']);
}
public function isAuthorized($user){
if(isset($user['grade']) && $user['grade']=== 3){
return true;
}
}
}

Related

Cakephp 3.0 Login

I'm facing trouble with my login system. I managed to register my user in my database but whenever I try to log in, it keeps prompting "Invalid email or password, try again".
This is my model:
<?php
namespace App\Model\Table;
use Cake\ORM\Table;
use Cake\Validation\Validator;
class UsersTable extends Table
{
public function validationDefault(Validator $validator)
{
return $validator
->notEmpty('email', 'A email is required')
->add('email', 'valid' , ['rule'=> 'email'])
->add('email', [
'unique' => ['rule' => 'validateUnique', 'provider' => 'table']
])
->requirePresence('email','create')
->notEmpty('password', 'A password is required')
->notEmpty('role', 'A role is required')
->add('role', 'inList', [
'rule' => ['inList', ['admin', 'author']],
'message' => 'Please enter a valid role'
]);
}
}
My controller:
<?php
namespace App\Controller;
use App\Controller\AppController;
use Cake\Event\Event;
use Cake\Network\Exception\NotFoundException;
class UsersController extends AppController
{
public function beforeFilter(Event $event)
{
parent::beforeFilter($event);
$this->Auth->allow(['add', 'logout']);
}
public function login()
{
if ($this->request->is('post')) {
$user = $this->Auth->identify();
if ($user) {
$this->Auth->setUser($user);
return $this->redirect($this->Auth->redirectUrl());
}
$this->Flash->error(__('Invalid email or password, try again'));
}
}
public function logout()
{
return $this->redirect($this->Auth->logout());
}
public function index()
{
$this->set('users', $this->Users->find('all'));
}
public function view($id)
{
if (!$id) {
throw new NotFoundException(__('Invalid user'));
}
$user = $this->Users->get($id);
$this->set(compact('user'));
}
public function add()
{
$user = $this->Users->newEntity();
if ($this->request->is('post')) {
$user = $this->Users->patchEntity($user, $this->request->data);
if ($this->Users->save($user)) {
$this->Flash->success(__('The user has been saved.'));
return $this->redirect(['action' => 'add']);
}
$this->Flash->error(__('Email already existed.'));
}
$this->set('user', $user);
}
}
AppController:
<?php
namespace App\Controller;
use Cake\Controller\Controller;
use Cake\Event\Event;
class AppController extends Controller
{
public function initialize()
{
$this->loadComponent('Flash');
$this->loadComponent('Auth', [
'authorize' => ['Controller'],
'loginRedirect' => [
'controller' => 'Articles',
'action' => 'index'
],
'logoutRedirect' => [
'controller' => 'Pages',
'action' => 'display',
'home'
]
]);
}
public function isAuthorized($user)
{
if (isset($user['role']) && $user['role'] === 'admin') {
return true;
}
return false;
}
public function beforeFilter(Event $event)
{
$this->Auth->allow(['index', 'view', 'display']);
}
}
login.ctp
<div class="users form">
<?= $this->Flash->render('auth') ?>
<?= $this->Form->create() ?>
<fieldset>
<legend><?= __('Please enter your username and password') ?></legend>
<?= $this->Form->input('email') ?>
<?= $this->Form->input('password') ?>
</fieldset>
<?= $this->Form->button(__('Login')); ?>
<?= $this->Form->end() ?>
</div>
I think the problem comes from the AppController
Have a quick look at this : CookBook CakePHP 3.0 Example Bookmarker Part 1
The login part is here : CookBook CakePHP 3.0 Example Bookmarker Part 2
Find the similarities with your project, try to make an analogy, a relation.
Thanks guys! Managed to find the answer after referring to the tutorials. Turns out i miss out
'authenticate' => [
'Form' => [
'fields' => [
'username' => 'email',
'password' => 'password'
All good now! Cheers =)

cakephp auth component is not working

class UsersController extends AppController {
var $uses = array('User', 'Feed', 'Author', 'Comment', 'Tag', 'SingleArticle', 'Category');
var $helpers = array('Html', 'Form');
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('signup');
}
public $components = array('Session', 'RequestHandler',
'Auth' => array(
'logoutRedirect' => array('controller' => 'users', 'action' => 'index'),
'authError' => "you can't access that page",
'authenticate' => array(
'Form' => array(// THIS IS WHERE YOU CHANGE THE DEFAULT FIELDS
'fields' => array('email' => 'email', 'pwd' => 'pwd'),
'passwordHasher' => 'Blowfish'
)
)
)
);
public function isAuthorized($user) {
return true;
}
public function login() {
if ($this->request->is('post')) {
if ($this->Auth->login()) {
$this->redirect(array('controller'=>'users','action'=>'mind'));
} else {
$this->Session->setFlash('login failed');
}
}
}
public function logout() {
$this->redirect($this->Auth->logout());
}
}
this is my userscontroller.php.
my appcontroller.php
public $components = array('Auth', 'RequestHandler');
public $pageTitle;
public function beforeFilter() {
$this->Auth->allow('index');
parent::beforeFilter();
}
my user.php
<?php
App::uses('AppModel', 'Model');
App::uses('BlowfishPasswordHasher', 'Controller/Component/Auth');
class User extends AppModel {
public $name = 'User';
var $useTable = 'fvf_users';
public function beforeSave($options = array()) {
if (isset($this->data['User']['pwd'])) {
$passwordHasher = new BlowfishPasswordHasher();
$this->data['User']['pwd'] = $passwordHasher->hash(
$this->data['User']['pwd']
);
}
return true;
}
}
please help me,my login page not worked.it will redirected to the same login page only.
i used the password hasing for blowfish method. please help me.thanks in advance.
which part is mistake in my code.what is the default password encryption method in cakephp.
Cakephp LOGIN not working...:(
Your fields array in config is incorrect. Assuming you db fields are email and pwd. The array needs to be 'fields' => array('username' => 'email', 'password' => 'pwd'). Your login form field names would also be email and pwd.

Deny admin routes for specific and not logged users

I have two groups id :
Group 1 => Admins
Group 2 => Users
I'm looking for a way to deny the access for the users which are not admin (so group 2 and not logged) . The function isAuthorized doesn't work, i mean it's always return true, i just don't know why . Thanks for your help
<?php
App::uses('Controller', 'Controller');
class AppController extends Controller {
public $components = array(
'Acl',
'Auth' => array(
'authorize' => array(
'Actions' => array('actionPath' => 'controllers')
)
),
'Session'
);
public $helpers = array('Html', 'Form', 'Session');
public function beforeFilter() {
parent::beforeFilter();
//Configure AuthComponent
$this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
$this->Auth->logoutRedirect = array('controller' => 'users', 'action' => 'login');
$this->Auth->loginRedirect = array('controller' => 'pages', 'action' => 'home');
if(isset($this->request->params["prefix"]) && $this->request->params["prefix"] == "admin"){
$this->layout = "admin";
} else {
$this->layout = "default";
}
}
public function isAuthorized() {
parent::isAuthorized();
if(isset($this->request->params["prefix"]) && $this->request->params["prefix"] == "admin" && $this->Auth->user('group_id') === 1){
return true;
}
else {
return false;
}
}
}
PagesController
<?php
class PagesController extends AppController {
/**
* This controller does not use a model
*
* #var array
*/
public $uses = array();
/**
* Displays a view
*
* #param mixed What page to display
* #return void
* #throws NotFoundException When the view file could not be found
* or MissingViewException in debug mode.
*/
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow();
}
public function display() {
$path = func_get_args();
$count = count($path);
if (!$count) {
return $this->redirect('/');
}
$page = $subpage = $title_for_layout = null;
if (!empty($path[0])) {
$page = $path[0];
}
if (!empty($path[1])) {
$subpage = $path[1];
}
if (!empty($path[$count - 1])) {
$title_for_layout = Inflector::humanize($path[$count - 1]);
}
$this->set(compact('page', 'subpage', 'title_for_layout'));
try {
$this->render(implode('/', $path));
} catch (MissingViewException $e) {
if (Configure::read('debug')) {
throw $e;
}
throw new NotFoundException();
}
}
public function admin_index() {
$title_for_layout = 'Dashboard';
$this->set(compact('title_for_layout'));
}
}
routes
*/
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
/**
* ...and connect the rest of 'Pages' controller's urls.
*/
Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
Router::connect('/admin', array('controller' => 'pages', 'action' => 'index', 'admin' => true));
To auto add prefix from action like admin_ you need to add the following line in your core.php file:
Configure::write('Routing.prefixes', array('admin'));
Then, the action PagesController::admin_index is accessible by /admin/pages/index instead of /pages/admin_index and the admin param is set to true so you can check it using $this->params['admin'] (see my code bellow).
Actually, in CakePHP all routes are denied by default but you allow all routes in PagesController by doing $this->Auth->allow() in the beforeFilter, you need to add an exception for admin.
To do so, in your AppController:
<?php
class AppController {
public $components = array(
'Auth' => array(
'loginAction' => array('controller' => 'users', 'action' => 'login');
'loginRedirect' => array('controller' => 'pages', 'action' => 'home');
'logoutRedirect' => array('controller' => 'users', 'action' => 'login');
'authorize' => array('Controller'),
)
) ;
public beforeFilter() {
parent::beforeFilter() ;
// Allow everything to not logged user except admin pages
if (isset($this->params["admin"])
&& $this->params["admin"]) {
$this->Auth->deny() ;
}
else {
$this->Auth->allow() ;
}
}
public isAuthorized() {
if (isset($this->params["admin"])
&& $this->params["admin"]) {
return $this->Auth->user('group_id') === 1 ;
}
return parent::isAuthorized() ;
}
} ;

Restricting and redirecting other user from admin in cakePHP

I'm getting issue after logging in the site. There are two kinds of users i.e. 'admin','employer'. When I've logged in by employer, I can access the restricted area of Admin. Below is the AppController of the site..
class AppController extends Controller {
public $helpers = array('Form', 'Html', 'Js', 'Time', 'Auth');
// Change template extension to .php instead of .ctp
var $ext = '.php';
public $components = array(
'Session',
'Auth' => array(
'loginAction' => array(
'controller' => 'users',
'action' => 'login'
),
'loginRedirect' => array('controller' => 'users', 'action' => 'index'),
'logoutRedirect' => array('controller' => 'users', 'action' => 'login'),
'authenticate' => array('Form' => array('fields' => array('username' => 'email'))),
'authorize' => array('Controller')
)
);
public function isAuthorized($user) {
// Admin can access every action
if (isset($user['type']) && $user['type'] === 'admin') {
return true;
}
// Default deny
return false;
}
public function beforeFilter() {
$this->Auth->allow(array('view', 'index','assessment','question'));
}
}
Now here is the controller which has methods for admin.
class TopicsController extends AppController {
public $scaffold = 'admin';
public function beforeFilter() {
if($this->Auth->user('type')!='employer'){
parent::beforeFilter();
$this->Auth->allow(array('view', 'index','moveup'));
} else {
$this->Auth->deny(array('view', 'index','moveup'));
$this->redirect(array('controller' => 'employer' , 'action' => 'index'));
}
}
public function isAuthorized($user) {
return true;
}
public function index() {
$this->set('topics', $this->Topic->children());
}
}
If admin URL is www.example.com/admin/topics , Employer is redirected to www.example.com/admin/employer which is not right URL to be redirected.
Also want to know about public $scaffold = 'admin'; as It's little unclear to me.
Please help me..
Ok.. Found one way to redirect, which made my issue solved for a now.. Still looking for proper answer if anybody has..
I changed code from
$this->redirect(array('controller' => 'employer' , 'action' => 'index'));
to
$this->redirect('employer');
..
EDIT: Thanks Alex, I've used
$this->redirect(array('controller' => 'employer' , 'action' => 'index', 'admin'=>false));
and it's working too..

Auth allow not working always redirects to login

I have this in orders_controller.php
function beforeFilter() {
$this->Auth->allow('checkout', 'checkout_confirm', 'checkout_done');
parent::beforeFilter();
}
When I try to go to orders/checkout it always redirects me to users/login
Don't know where to look for solution.
I have an app_controller.php in app/
class AppController extends Controller {
var $components = array(
'Email',
'RequestHandler',
'Session',
'Cookie',
'Auth' => array(
'fields' => array(
'username' => "email",
'password' => "password"
),
'autoRedirect' => true,
'loginAction' => array('controller' => "users", 'action' => "login", 'admin' => false), // 'loginRedirect' => array('controller'
=> "users", 'action' => "check_account") // 'loginRedirect' => array('admin' => false, 'controller' => "users", 'action' => "account_home")
),
'Acl',
'Loviu'
);
var $helpers = array('Html', 'Form', 'Paginator', 'Session', 'Image', 'Javascript', 'Time', 'Text', 'Embed', 'Loviu');
var $uses = array('User', 'Shelf');
function beforeFilter() {
if (isset($this->params['admin']) && (1 == $this->params['admin'])) {
$this->testAccess("admin");
}
if($this->params['controller'] == 'pages'){
$this->Session->write('menu.active', 'inactive');
}
$this->Auth->allow('display');
if (false == $this->Session->check('Auth.User')) {
if (empty($this->data)) {
$cookie = $this->Cookie->read('Auth.User');
if (false == is_null($cookie)) {
// login user
if ($this->Auth->login($cookie)) {
// delete auth message
$this->Session->delete('Message.auth');
}
else {
// delete invalid cookie
$this->Cookie->delete('Auth.User');
}
} elseif(!$this->Session->read('loggedOut') && $this->params['action'] != 'login_fb') {
$this->__checkFBStatus();
}
}
}
$this->set('user_id', $this->User->id);
$this->set('lng', $this->Cookie->read("language") ? $this->Cookie->read("language") : 'eng');
parent::beforeFilter();
}
I would also put the $this->Auth->allow('checkout', 'checkout_confirm', 'checkout_done');line in your app_controller. In my experience, sometimes the problem is that the system gets confused about which controller this action belongs to, depending on how your code is setup.
Here is what I use in my app_controller that has been perfect, in case it helps:
function beforeFilter() {
$this->allowAccess();
}
private function allowAccess() {
// this actually searches the URL to see what controller you're accessing, and allows actions for that controller.
if(in_array($this->name, array('Pages'))) {
$this->Auth->allow(array('home','blog','index'));
}
}
This specificity has saved me so much trouble, and calling the Auth->Allow in app_controller is where it really should be. Hope this helps!
I had the same problem and solved for my project.
My cakephp version 3. While you loadcomponent just put loginaction.
class AppController extends BaseController
{
public function initialize()
{
$this->loadComponent('Flash');
$this->loadComponent('Auth', [
'loginAction' => [
'controller' => 'Admin',
'action' => 'login',
'plugin' => 'Admin'
],
'loginRedirect' => [
'controller' => 'admin',
'action' => 'dashboard'
],
'logoutRedirect' => [
'controller' => 'admin',
'action' => 'login'
]
]);
}
}
hope helps others.
#rncrtr's answer worked for me, but I had to add the parent::beforeFilter() to the allowAccess method:
public function beforeFilter() {
parent::beforeFilter();
$this->allowAccess();
}
private function allowAccess() {
if (in_array($this->name, array('Pages'))) {
$this->Auth->allow(array('home','index','display'));
}
}
Oh yeah, I also had to add display to the allow array.
if you work on cakephp 2.x you must do like this :
function beforeFilter(){
$this->Auth->allow(array('action you want to allow1','action you want to allow2'));
}
allow(array()) instead allow()
---put that code into controller have action you want allow access without login
if you use $this->Auth->allow() you must call parent::beforeFilter(); in function beforeFilter() like this :
function beforeFilter(){
parent::beforeFilter();
$this->Auth->allow('add','view');
}

Resources