I have followed pretty much the tutorial from the CakePHP website to add authentication to my website (except that I do not need any roles on my website, but just an admin login). On my machine the whole authentication works and also which pages I can access only as admin. I have copied the folder and the database to my web hoster, but there I have problems logging in.
This is what my code looks like:
in config/routes.php I have:
Router::prefix('admin', function($routes) {
$routes->connect('/', ['controller'=>'Users','action'=>'login']);
$routes->fallbacks('InflectedRoute');
});
in src/Controller/Admin/UsersController.php
namespace App\Controller\Admin;
use App\Controller\AppController;
use Cake\Event\Event;
class UsersController extends AppController {
public function beforeFilter(Event $event) {
parent::beforeFilter($event);
$this->Auth->allow(['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(__('Please check your username and password.'));
}
}
}
The entity User contains a method to do the hashing:
protected function _setPassword($password)
{
return (new DefaultPasswordHasher)->hash($password);
}
Finally, in Controller/AppController.php I have implemented the following, that should allow every logged-in user to access all pages.
class AppController extends Controller
{
public function initialize()
{
parent::initialize();
$this->loadComponent('Flash');
$this->loadComponent('Auth', [
'loginRedirect' => [
'controller' => 'requests',
'action' => 'index'
],
'logoutRedirect' => [
'prefix' => false,
'controller' => '/'
]
]);
}
public function beforeFilter(Event $event)
{
parent::beforeFilter($event);
if($this->request->session()->check('Auth.User.id')) {
$this->layout = 'admin';
}
}
public function isAuthorized($user)
{
return true;
}
}
As I said, this works on my local machine. However, on the server, I always get the following error:
You are not authorized to access that location.
I tried various PHP versions, to make sure the error is not there. Using printouts, I could see that I pass the if($user) check in the login() method. However, now I really don't know how to proceed and I'm pretty clueless about possibly solutions. I have installed CakePHP in a subdomain on the webhoster - could that be a problem?
Related
I have installed users plugin with all other 5 plugins for different social login. When i login normally, it gives me a redirect URL error and when i click to the login with Facebook, it takes me to myproject/auth/Facebook. I don't know what i have to create for this Url just need little guidance. Thank you in Advance
App Controller
class AppController extends Controller
{
public function initialize()
{
parent::initialize();
// $this->loadComponent('Security');
$this->loadComponent('Flash');
$this->loadComponent('RequestHandler');
$this->loadComponent('CakeDC/Users.UsersAuth');
}
public function beforeRender(Event $event)
{
if (!array_key_exists('_serialize', $this->viewVars) &&
in_array($this->response->type(), ['application/json', 'application/xml'])
) {
$this->set('_serialize', true);
}
}
}
I have Added this Code in Bootstrap.php
Configure::write('Users.Social.login', true); //to enable social login
Configure::write('OAuth.providers.facebook.options.clientId', '8660982830167491');
Configure::write('OAuth.providers.facebook.options.clientSecret', 'secret');
Configure::write('OAuth.providers.google.options.clientId', '7724091450376-birdmh5a3t48b8mg9knq0lonup6aeomk.apps.googleusercontent.com');
Configure::write('OAuth.providers.google.options.clientSecret', 'secret');
Plugin::load('CakeDC/Users', ['routes' => true, 'bootstrap' => true]);
Configure::write('OAuth.providers.facebook.options.clientId', '17076687932896982');
Configure::write('OAuth.providers.facebook.options.clientSecret', 'be3ca9743ae0bd278ee61c4bda770907fc');
Configure::write('OAuth.providers.twitter.options.clientId', '1082264240790-8ns1ohig1f3iqlgo9okac3kr3p50j44det.apps.googleusercontent.com');
Configure::write('OAuth.providers.twitter.options.clientSecret', 'odSeNKMK5dWpQpfNu8LbGX_K');
I've followed the tutorial and all the CakePHP Authorization guide and I can't get my isAuthorized() method to be called. My understanding (correct me if I am wrong, which is incredibly likely) is by delegating authorize to the specific controllers by doing 'authorize'->['Controller'] in AppController.php, when a method in UsersController is called, in this case 'add', UsersController would run the isAuthorized() method I defined. I was testing to see if this method ran at all outputting a flash->error message right when isAuthorized() is called but nothing happens. If I explicitly call isAuthorized($hardcodeduser) in my beforeFilter()method it will work but only if I hard code a user.
The way the method is supposed to work is: If a registered user requests to add/create a new user, the system checks to see if the user has admin/staff level permissions (which is just a 0 or 1 value in the database) and if the user does not have permission then it redirects to the home screen with an error message that says "You are not authorized to access that function".
Any help or suggestions or other links to follow would be much appreciated!
class AppController extends Controller {
public $components = ['Flash', 'Auth', 'Session'];
public function initialize() {
$this->loadComponent('Flash');
$this->loadComponent('Auth', [
'authorize' => ['Controller'],
'loginRedirect' => [
'controller' => 'Articles',
'action' => 'index'
],
'logoutRedirect' => [
'controller' => 'Pages',
'action' => 'display',
'home'
]
]);
}
public function beforeFilter(Event $event) {
$this->Auth->authorize = 'Controller';
}
public function isAuthorized($user) {
if(isset($user['is_staff']))
return true;
return false;
}
}
class UsersController extends AppController {
public function beforeFilter(Event $event) {
parent::beforeFilter($event);
$this->Auth->allow(['logout']);
}
public function isAuthorized($user) {
$this->Flash->error(__('Test Message PLEASE WORK'));
if($this->request->action === 'add') {
$isStaff = $user['is_staff'];
if($isStaff == 0) {
$this->redirect($this->Auth->redirectUrl());
$this->Flash->error(__('Not authorized to access this function'));
return false;
}
}
return parent ::isAuthorized($user);
}
}
Generally your assumption is correct, Controller::isAuthorized() is going to be invoked automatically when using the controller authorization handler.
The problem with your code is that in your UsersController::beforeFilter() method you are explicitly allowing the add method to be accessed by everyone (it won't even require authentication):
$this->Auth->allow(['logout', 'add']);
You have to understand that once a method is allowed, there will be no further checks made by the auth component, see AuthComponent::startup().
Also note that you don't need to redirect and set a flash message manually, the component will do that for you, you just need to configure it appropriately using the authError and unauthorizedRedirect options, see Cookbook > Components > Authentication > Configuration options
As we following the Cake blog tutorial,
they made a little mistake, that function "isAuthorized" never be called.
And I did take a time to research it.
Solution is
Adding this line when load component "Auth":
'authorize' => array('Controller'),
so the code should looks something like this:
$this->loadComponent('Auth', [
'loginRedirect' => [
'controller' => 'Articles',
'action' => 'index'
],
'logoutRedirect' => [
'controller' => 'Pages',
'action' => 'display',
'home'
],
'authorize' => array('Controller'),
]);
Hope it help some one saving time :)
From cakephp 3.x documentation: you can configure authorization handlers in your controller’s beforeFilter() or initialize() methods using an array:
// Basic setup
$this->Auth->config('authorize', ['Controller']);
// Pass settings in
$this->Auth->config('authorize', [
'Actions' => ['actionPath' => 'controllers/'],
'Controller'
]);
i am new in cakephp. i am making a logging system in cakephp 2.x .. i am stuck here
UsersController.php extending AppController
public function login()
{
if ($this->request->is('post')) {
if ($this->Auth->login()) {
$this->redirect($this->Auth->redirect());
} else {
$this->Session->setFlash('Your email/password combination was incorrect');
}
}
}
the problem is that it is not checking that whether the email and password typed by the user is correct or not..and is logging the user in without checking .. i have never used the auth component before ... so i am feeling hard to grasp that how this function is checking the email and password from the database as on the internet and the cakephp website they are using this function to check whether the user has logged in successfully or not./i always used sql queries but i dont know how this component is working .. please correct this function and explain me where it is checking the email and password from the database
here is my
AppController
class AppController extends Controller {
public $components = array(
'Session',
'Auth'=>array(
'loginRedirect'=>array('controller'=>'users', 'action'=>'admin'),
'logoutRedirect'=>array('controller'=>'users', 'action'=>'admin'),
'authError'=>"You can't access that page",
'authorize'=>array('Controller')
)
);
public function isAuthorized($user) {
}
public function beforeFilter() {
$this->Auth->allow('index');
}
}
class AppController extends Controller {
// added the debug toolkit
// sessions support
// authorization for login and logut redirect
public $components = array(
'Session',
'Cookie',
'Auth' => array(
'authenticate' => array('Form' => array('fields' => array('username' => 'email', 'password' => 'password'),)),
'authorize' => array('Controller'))
);
public function isAuthorized($user) {
return true;
}
}
please replace the co in app controller.
I am start going through the cakephp tutorials, I copy the source code exactly as shown in the tutorial.
I have done the Blog tutorial and all seems good, now I am onto the "Simple Authentication and Authorization Application" (http://book.cakephp.org/2.0/en/tutorials-and-examples/blog-auth-example/auth.html) tutorial, but are running into this issue.
The add page loads fine:
".../app/webroot/index.php/Users/add"
After hitting submit, it redirects me to this url (with the additional "Users" string) and with an error message.
".../app/webroot/index.php/Users/Users/add"
Missing Method in UsersController
Error: The action Users is not defined in controller UsersController
Error: Create UsersController::Users() in file: app/Controller/UsersController.php.
class UsersController extends AppController {
public function Users() {
}
}
Let me know where I should start checking, Thanks.
AppController
class AppController extends Controller {
public $components = array(
'Session',
'Auth' => array(
'loginRedirect' => array('controller' => 'posts', 'action' => 'index'),
'logoutRedirect' => array('controller' => 'pages', 'action' => 'display', 'home'),
'authorize' => array('Controller') // Added this line
)
);
public function beforeFilter() {
$this->Auth->allow('index', 'view');
}
public function isAuthorized($user) {
// Admin can access every action
if (isset($user['role']) && $user['role'] === 'admin') {
return true;
}
// Default deny
return false;
}
}
Because I still can't comment, I'll tell you here and edit this answer if I know it.
Show me your AuthComponent configuration in AppController.php.
EDIT:
Answer is in the comments below. :)
I have been reading Stack Overflow questions all afternoon trying to figure this out..
I have a users controller with index/login/logout/register functions but also has admin_index/admin_add/admin_edit/admin_delete etc.
I have Auth component enabled and in my users_controller i am trying to deny access to the admin_* pages if the Auth.User.role != 'admin', when i enable the $this->Auth->authorize = 'controller'; it denies access to the site.com/admin/users/ page and also seems to kill the logout function even tho my account has the role set to admin.
However if i type the url in i get redirected back to the main homepage.
users_controller.php
<?php
class UsersController extends AppController {
var $name = 'Users';
function beforeFilter(){
parent::beforeFilter();
$this->Auth->authorize = 'controller';
$this->Auth->allow('register');
}
function isAuthorized() {
if ($this->Auth->user('role') != 'admin') {
$this->Auth->deny('admin_index','admin_view', 'admin_add', 'admin_edit','admin_delete');
}
}
app_controller.php
<?php
class AppController extends Controller {
var $components = array('Auth', 'Session');
function beforeFilter() {
$this->Auth->loginAction = array('controller'=>'users','action'=>'login', 'admin'=>false);
$this->Auth->logoutRedirect = array('controller'=>'users','action'=>'logout');
$this->Auth->loginRedirect = array('controller'=>'shows', 'action'=>'index');
$this->Auth->autoRedirect = false;
$this->Auth->allow('home');
}
My Second question relates to the way $this->Auth->deny('page'); redirects the user, as far as i can tell it redirects to / but i need it to redirect back to the users controller.
Hope it all makes sense and i have provided enough info..
The root of your problem is probably your isAuthorized() method. This should simply return true or false, and indicates whether an authenticated user is AUTHORIZED to access a particular action.
It's difficult to say why you'd be redirected to the home page instead of the login page. But it's possible that you have other code somewhere that's messing things up.
Try modifying your code as below and see if that doesn't help get things working:
app_controller.php
<?php
class AppController extends Controller {
var $components = array('Session', 'Auth' => array(
'loginAction' => array('controller'=>'users','action'=>'login', 'admin'=>false),
'logoutRedirect' => array('controller'=>'users','action'=>'logout'),
'loginRedirect' => array('controller'=>'shows', 'action'=>'index'),
'autoRedirect' => false,
'authorize' => 'controller'
);
function beforeFilter() {
$this->Auth->allow('home');
}
function isAuthorized() {
if (!empty($this->params['prefix']) && $this->params['prefix'] == 'admin') {
if ($this->Auth->user('role') != 'admin') {
return false;
}
}
return true;
}
?>
users_controller.php
<?php
class UsersController extends AppController {
var $name = 'Users';
function beforeFilter(){
parent::beforeFilter();
$this->Auth->allow('register');
}
?>
I moved all the Auth settings to the declaration in the $components variable because it seems cleaner and to make more sense to declare default values there. But this is more a matter of personal preference and it shouldn't have a real effect on the code's functioning.
Also, note that if you set autoRedirect to false, you'll have to redirect logged-in users manually in your Users::login() action, getting the loginRedirect value with $this->Auth->redirect().
I don't see any reason why you should be sent to / when you're not logged in and you try to access a blocked action, but maybe it will be easier to figure out after you fix the above. **
you should do this like...
function beforeFilter()
{
if($this->Auth->user('role')=='admin'){
$this->Auth->allow('admin_view','admin_controls');//put your all admin actions separated by comma
}
else
{
$this->Auth->allow('home');//put your all non-admin actions separated by comma
}
}
hope it will work... if any problem let me know....