Display username after login in cakephp3 - cakephp

I want to display username after login in cakephp3. I write follow code but part of show username doesn't work. user after login redirect to main page.
Hi <?php print $this->request->session()->read('User',$user); ?>
login in UserController:
public function login() {
if ($this->request->session()->read('login_ok') == '1') {
$this->redirect(['controller' => 'users', 'action' => 'main']);
}
if ($this->request->is('post')) {
//$hasher = new DefaultPasswordHasher();
$count = $this->Users->find()
->where(['username' => $this->request->data['username'],
// 'password' => $this->request->data['password']])
'password' => md5($this->request->data['password'])])
->count();
if ($count > 0) {
$result = true;
$this->request->session()->write('User', $user); //store username
$this->request->session()->write('login_ok', '1');
$this->redirect(['controller' => 'users', 'action' => 'main']);
} else {
$result = false;
}
$this->set('result', $result);
}
}
public function main() {
if ($this->request->session()->read('login_ok') != '1') {
$this->redirect(['controller' => 'users', 'action' => 'login']);
}
$query = $this->request->session()->write('User',$user);
$this->set('user', $query);
}
and this main.ctp codes:
Hi <?php print $this->request->session()->read('User', $user); ?>
Can you help in making this Code OR Suggest a new code ?

You should really be using the cakephp AuthComponent and the functions that's made for this for example identifiying the user trying to login with identify().
There is really no point using a framework if you're not going to use the functions provided by the framework as N Nem pointed out in the comments.
In the snippet you posted, you seem to never set the $user variable when you write to the session. You need to set it to be able to read it.
The following code is how you're supposed to do it in Cakephp 3 i really suggest you use that approach.
AppController.php
public function initialize()
{
$this->loadComponent('Auth', [
'loginAction' => [
'controller' => 'Users',
'action' => 'login'
],
'loginRedirect' => [
'controller' => 'Start',
'action' => 'index'
],
'logoutRedirect' => [
'controller' => 'Users',
'action' => 'login'
],
'authenticate' => [
'Form'
],
]);
}
UsersController.php
public function login()
{
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(__('Username or password is incorrect'), [
'key' => 'auth'
]);
}
}
}
Model/Entity/User.php
protected function _setPassword($password)
{
return (new DefaultPasswordHasher)->hash($password);
}

Related

CakePHP 2.x: Why is my /admin/user/login stuck in a redirect loop?

I have created a little project with an admin section. I am using admin routes to redirect to admin actions in my controllers. The website has pages that are available to everyone with no login required. To access the /admin or /admin/users, etc... You must login.
I have spread my admin actions across my controllers like "admin_login", "admin_users", ...
So my question is, when someone goes to /admin/users or some other adminpage, I have to check in each controller action if the user is in the session and otherwise redirect to thelogin form.
Is there a way to do this in one place? I used a beforefilter in my AppController class.
When using something like this, I get an infinite loop:
AppController.php
class AppController extends Controller {
public $helpers = array('Paginator','Acl.AclHtml');
public $components = array('Acl', 'Session',
'Auth' => array(
'authError' => 'You are not authorized to access that location.',
'authorize' => array(
'Actions' => array(
'actionPath' => 'controllers')
),
'controllers' => array('users')
));
public function beforeFilter() {
if(isset($this->request->prefix) && ($this->request->prefix == 'admin')){
$username = $this->Session->read('Admin.username');
if (empty($username)) {
$this->redirect (array(
'controller'=>'users',
'action'=>'login',
'admin'=>true
));
} else {
$this->redirect (array(
'controller'=>'admin',
'action'=>'dashboard',
'admin'=>true
));
}
}
// LDAP
$server_ip = $_SERVER['SERVER_ADDR'];
$ldapIp = ClassRegistry::init('LdapIp');
$ldapIpCount = $ldapIp->find('count', array('conditions' => array('ldap_ip' => $server_ip)));
if ($ldapIpCount >= 1) {
$this->Auth->authenticate = array('Ldap');
} else {
$this->Auth->authenticate = array('Form');
}
$this->Auth->authenticate = array('Form');
$this->Auth->allow();
if (!$this->Auth->isAllow($this)) {
$this->set(array(
'message' => array(
'text' => __('un aunthaticated request'),
'type' => 'error',
'status' => "401"
),
'_serialize' => array('message')
));
throw new ForbiddenException();
}
}
}
The front login with LDAP (Active directory).
UsersController.php
App::uses('AppController', 'Controller');
App::uses('Sanitize', 'Utility');
class UsersController extends AppController {
public $components = array('Paginator', 'Session', 'RequestHandler', 'Auth', 'Acl');
public function admin_login() {
$this->layout = 'admin_login';
if ($this->request->is('post')) {
$username = $this->request->data['User']['username'];
$password = $this->request->data['User']['password'];
$password = Security::hash($password, null, true);
$logged_in = $this->User->find('count', array('conditions' => array('User.username' => $username, 'User.password' => $password, 'User.role' => 'Admin', 'User.active' => 1)));
if ($logged_in >= 1) {
$this->Session->setFlash(__('Login successful!'), 'default', array('class' => 'alert alert-success'));
$users = $this->User->find('first', array('conditions' => array('User.username' => $username, 'User.password' => $password, 'User.role' => 'Admin', 'User.active' => 1)));
$this->Session->write('Admin.id', $users['User']['id']);
$this->Session->write('Admin.username', $users['User']['username']);
$this->Session->write('Admin.group_id', $users['User']['group_id']);
$this->Session->write('Admin.full_name', $users['UserProfile']['fname'] . " " . $users['UserProfile']['lname']);
$this->redirect(array('controller' => 'admin', 'action' => 'dashboard', 'admin' => true));
} else {
$this->Session->setFlash(__('Username or password is incorrect!'), 'default', array('class' => 'alert alert-error'));
}
}
}
public function admin_logout() {
$this->Session->delete("Admin");
//$this->Session->destroy();
$this->Session->setFlash(__('Logged out successful!'), 'default', array('class' => 'alert alert-success'));
$this->redirect(array('controller' => 'users', 'action' => 'login', 'admin' => true));
}
}
Yoy are getting an infinite loop because beforeFilter() will be called when you attempt to access /admin/users/login.
The proper way of dealing with your needs is setting up the Auth Component.
Once you've set up component, in UsersController::beforeFilter() you have to allow access to those actions that don't require login by means of the allow() method. E.g.
public function beforeFilter() {
$this->Auth->allow(array('signup'));
parent::beforeFilter();
}
This is also applicable to any other controller with actions that need to be accessed by non logged in users.
The loginAction you define in the Auth component configuration will be automatically allowed access.
In the blog tutorial you will find a good example of the Auth component usage.
Edit
As mentioned, AppController::beforeFilter() is always called, even when you try to access /admin/users/login. To prevent this from happening, try adding the following condition:
if (empty($username) && $this->action!='login') {
$this->redirect (array(
'controller'=>'users',
'action'=>'login',
'admin'=>true
));
}
You wouldn't need this if you allowed AuthComponent to take care of authentication for you.
Still, there's no guarantee that your code will work as expected. You are making your life difficult by not using AuthComponent to its fullest. I recommend that you research on the topic:
Creating Custom Authorize objects in the Cookbook 2.x
LdapAuth in cakephp 2.0 in Stack Overflow

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..

Checking user role on login using CakePHP?

I want to create an admin panel for my site, for this I've created admin.ctp. In DB table name user contain column role, where role=admin/regular(user).
There is only one login form, and the question is, Is it possible to place a 'check' that if user.role=admin then redirect to the admin/user/dashboard and if user.role=regular then layout=default? my AppController.php contains:
function beforeFilter(){
$this->Auth->allow('index','view','login','home');
$this->set('admin',$this->_isAdmin());
$this->set('logged_in',$this->Auth->loggedIn());
$this->set('current_user',$this->Auth->User());
if ((isset($this->params['prefix']) && ($this->params['prefix'] == 'admin'))) {
$this->layout = 'admin';
}
And usersController.php
function beforeFilter(){
parent::beforeFilter();
$this->Auth->allow('*');
if($this->action=='add' || $this->action=='edit'){
$this->Auth->authenticate=$this->User;
}
}
function login(){
if(!($this->Auth->loggedIn())){
if ($this->request->is('post')) {
if ($this->Auth->login()) {
if($user['role'] === 'admin'){
$this->redirect($this->Auth->redirect('admin',array('controller' => 'user','action' => 'admin_dashboard')));
}
$this->redirect($this->Auth->redirect(array('controller' => 'posts','action' => 'index')));
} else {
$this->Session->setFlash('Your username/password combination was incorrect.',
'alert',array(
'plugin' => 'TwitterBootstrap',
'class' => 'alert-error'
));
$this->set('forget', 'Forgot Your Password');
}
}
}else
{
$this->redirect($this->Auth->redirect(array('controller' => 'posts','action' => 'index')));
}
}
using cakephp 2.2.3.
thanks in advance!
This is how I would do it (remember to change field('name') accordingly with your group model).
if ($this->Auth->login())
{
this->User->Group->id = $this->Auth->user('group_id');
switch ($this->User->Group->field('name'))
{
case 'admin':
$this->redirect($this->Auth->redirect('admin',array('controller' => 'user','action' => 'admin_dashboard')));
break;
case 'regular':
$this->redirect($this->Auth->redirect(array('controller' => 'posts','action' => 'index')));
break;
default:
//...
break;
}
}
In AppController set:
$this->Auth->authorize = array('Controller');
And then do the following
public function isAuthorized($user = null)
{
if (isset($this->request->params['admin']))
{
if(!isAdmin)
{
return false;
}
}
return true;
}
CakePHP actually already provides a useful Authentication and Authorization framework that's trivial to enable.
Here's how to authorize based on a role stored in the database, from the CakePHP manual. I also included an example beforeFilter() that changes the login redirect action if the user is an admin:
AppController.php:
public $components = array(
'Auth' => array(
'authorize' => array('Controller'),
'loginRedirect' => array('/'),
));
public function beforeFilter() {
// This allows us to use $user in all controllers.
$this->set('user', $this->Auth->user());
// If the user is an admin, override the loginRedirect
if ('admin' === $this->Auth->user('role')) {
$this->Auth->loginRedirect = array(
'controller' => 'users',
'action' => 'admin_dashboard',
));
}
}
UsersController.php:
public function isAuthorized($user) {
// Ensure the user has a valid role. If not, deny access to all actions:
if ((!isset($user['role'])) || ('' === $user['role'])) return false;
// If we're trying to access the admin view, verify permission:
if ('admin_dashboard' === $this->action)
{
if ('admin' === $user['role']) return true; // User is admin, allow
return false; // User isn't admin, deny
}
return true;
}
There are many ways you can arrange the authorization, so adjust the if/else statements to best suit your needs. The isAuthorized() method is relatively simple, you just need to return true if you want to allow access, or false if you don't.
I actually want to post some code to perhaps shed light on this subject for myself as well.
I have achieved a simple dashboard for each user that extends the /Users/view - my next step is trying to get User-specific access to each set of data
AppController
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() {
//Configure AuthComponent
$this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
$this->Auth->logoutRedirect = array('controller' => 'users', 'action' => 'login');
$this->Auth->loginRedirect = array('controller' => 'users', 'action' => 'dashboard');
$this->Auth->allow('display');
}
}
UsersController
public function dashboard() {
$id = $this->Auth->user('id');
$this->set('user', $this->User->read(null, $id));
$group_name = $this->User->Group->field('name', array('id' => $this->Auth->User('group_id')));
$this->redirect = array('controller' => 'users', 'action' => 'dashboard');
}
dashboard.ctp
$this->extend('/Users/view');
<?php public function dashboard() {
$id = $this->Auth->user('id');
$this->set('user', $this->User->read(null, $id));
$group_name = $this->User->Group->field(
'name', array('id' => $this->Auth->User('group_id'))
);
$this->redirect = array('controller' => 'users', 'action' => 'dashboard');
}
?>

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