I am unable to get the Auth component to login once passed credentials in a post method.
I am using CakePHP2.*
I am trying to write a web service.
Please below the code i have written to configure the Auth component in the AppController and below that the UserController for the User model
class AppController extends Controller {
public $components = array(
'DebugKit.Toolbar',
'Session',
'Auth' => array(
'loginRedirect' => array('controller' => 'user', 'action' => 'view'),
'logoutRedirect' => array('controller' => 'user', 'action' => 'home'),
'authenticate' => array('Form' => array('fields' => array('username'=>'username','password'=>'password'))),
'userScope'=> array('User.active_yn' => 1),
'userModel'=>'User',
'loginAction'=>array('controller' => 'user', 'action' => 'login'),
'autoRedirect'=>true,
'authError'=>'You dont have access to that area. Please login first.',
'loginError'=>'Username or password entered is incorrect. Please try again.',
'authorize' => array('Controller') // Added this line
)
);
public function isAuthorized($user) {
// Admin can access every action
if (isset($user['active_yn']) && $user['active_yn'] === 1) { //admin
return true;
}
// Default deny
return false;
}
public function beforeFilter() { }
}
class UserController extends AppController {
public $helpers = array('Html', 'Form', 'Session');
public $components = array('Session');
public $validate = array(
'email' => array('rule' => 'notEmpty')
);
public function index() {
$this->set('User', $this->User->find('all'));
}
public function view($id = null) {
if (!$id) {
throw new NotFoundException(__('Invalid User'));
}
$User = $this->User->findById($id);
if (!$User) {
throw new NotFoundException(__('Invalid User'));
}
$this->set('User', $User);
}
public function login() {
if ($this->request->is('post')) {
if ($this->Auth->login()) {
return $this->redirect($this->Auth->redirect());
}
$this->Session->setFlash(__('Invalid username or password, try again'));
}
$this->set('request', $this->request->data);
}
public function logout() {
return $this->redirect($this->Auth->logout());
}
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('view','login','logout');
}
}
Your controller names in the Auth configuration need to be in plural
Related
I am working on a personal project and I have searched through multiple topics that are related to my issue and I cannot find a solution to my problem.
Whenever I enter an email and password on my login page it always give me an invalid username or password pop up. I debugged a part of code in my UserloginController and it just returns false. There is probably a problem here but i cannot see it.
Some solutions for other people were to change the VARCHAR length of the password field, my password field is already a VARCHAR(255) and it hashes properly so this is not the problem.
Here is my AppController
class AppController extends Controller
{
public function isAuthorized($user = null)
{
// Any registered user can access public functions
if (empty($this->request->params['prefix'])) {
return true;
}
// Only admins can access admin functions
if ($this->request->params['prefix'] === 'admin') {
return (bool)($user['role'] === 'admin');
}
// Default deny
return false;
}
public function initialize()
{
$this->loadComponent('Flash');
$this->loadComponent('Auth', [
'authenticate' => [
'Form' => [
'userModel' => 'userlogin',
'fields' => [
'username' => 'email',
'password' => 'password'
]
]
],
'loginAction' => [
'controller' => 'userlogin',
'action' => 'login'
],
'logoutRedirect' => [
'controller' => 'userlogin',
'action' => 'login'
],
]);
// Allow the display action so our pages controller
// continues to work.
$this->Auth->allow(['display']);
}
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);
}
}
}
Here is my UserLoginController
class UserloginController extends AppController
{
public function initialize() {
parent::initialize();
$this->Auth->allow(['logout', 'add']);
}
//login
public function login(){
if ($this->request->is('post')) {
$user = $this->Auth->identify();
debug($this->Auth->identify()); // Returns False
if ($user) {
$this->Auth->setUser($user);
return $this->redirect($this->Auth->redirectUrl());
}
$this->Flash->error('Your username or password is incorrect.');
}
}
public function logout() {
$this->Flash->success('You are now logged out.');
return $this->redirect($this->Auth->logout());
}
public function beforeFilter(Event $event) {
parent::beforeFilter($event);
$this->Auth->allow('logout', 'login', 'index', 'add'); //you can add others here...
}
}
And Here is my Login.ctp
<br>
<div class="index large-4 medium-4 large-offset-4 medium-offset-4 columns">
<div class="panel">
<h1>Login</h1>
<?= $this->Form->create(); ?>
<?= $this->Form->input('email'); ?>
<?= $this->Form->input('password'); ?>
<?= $this->Form->button('Login'); ?>
<?= $this->Form->end(); ?>
Any sort of help will be greatly appreciated!
I'm looking for a solution to my problem. I'm trying create a webservice using CakePHP 2.
I created a CRUD and configured using AuthComponent to login. The AuthComponent was configured to use Form. When I try execute some function of controller to return a JSON doesn't works and show me code of page index.php
I think if I do configure Basic Auth works, but when I try add Basic Auth in $components it's opened access, all actions can be access on browser.
How could I configure Basic and Form of AuthComponent to works together ?
I'm trying this, but doesn't works, because all actions are opened to access
class AppController extends Controller {
public $components = array("RequestHandler", "Auth", "Session");
public function beforeFilter(){
$this->Auth->authenticate = array(
'Basic' => array('userModel' => 'User',
'fields'=> array(
'username' => 'email',
'password' => 'senha'
),
'scope' => array(
'User.status' => 1
)
),
'Form' => array('userModel' => 'User',
'fields'=> array(
'username' => 'email',
'password' => 'senha'
),
'scope' => array(
'User.status' => 1
)
),
);
$this->Auth->loginAction = array(
'controller' => 'users',
'action' => 'login'
);
$this->Auth->loginRedirect = array(
'controller' => 'matriculas',
'action' => 'index'
);
$this->Auth->logoutRedirect = array(
'controller' => 'users',
'action' => 'login'
);
$this->Auth->authorize = "Controller";
$this->Auth->authError = "Efetue login de acesso";
$this->Auth->allow("login");
}
public function isAuthorized($user) {
if (isset($user['role']) && $user['role'] === 'admin') {
return true; // Admin pode acessar todas actions
}
return false; // Os outros usuários não podem
}
}
UsersController
class UsersController extends AppController {
public $components = array('Paginator');
public function index() {
$this->User->recursive = 0;
$this->set('users', $this->Paginator->paginate());
}
public function add() {
if ($this->request->is('post')) {
$this->User->create();
if ($this->User->save($this->request->data)) {
$this->Session->setFlash(__('The user has been saved.'));
return $this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The user could not be saved. Please, try again.'));
}
}
}
public function edit($id = null) {
if (!$this->User->exists($id)) {
throw new NotFoundException(__('Invalid user'));
}
if ($this->request->is(array('post', 'put'))) {
if ($this->User->save($this->request->data)) {
$this->Session->setFlash(__('The user has been saved.'));
return $this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The user could not be saved. Please, try again.'));
}
} else {
$options = array('conditions' => array('User.' . $this->User->primaryKey => $id));
$this->request->data = $this->User->find('first', $options);
}
}
public function login(){
$this->layout = "layout";
if($this->request->is("post")){
if ($this->Auth->login()) {
$this->redirect($this->Auth->redirect());
}else{
$this->Session->setFlash(__('Usuário ou senha inválido'));
}
}
}
public function logout(){
$this->redirect($this->Auth->logout());
}
/********** WEB SERVICES FUNCTIONS *********/
/** return all users **/
public function findAll(){
$this->set("users", $this->User->find('all'));
$this->set(array(
"_serialize" => 'users',
));
}
/** add new user from app **/
public function addUserFromApp(){
$this->layout=null;
$data = $this->request->input("json_decode", true);
echo $data;
}
}
I just started trying to learn cakephp auth, i just copied and pasted the code, trying to understand it. I can't figure out what is directly the redirect
//app controller
//is empty i know in some cases you put it here, i'm just tested it in the user controller
//user controller
public $components = array('Paginator',
'Session',
'Auth' => array(
'loginAction' => array(
'controller' => 'users',
'action' => 'login',
'plugin' => 'users'
),
'authError' => 'Did you really think you are allowed to see that?',
'authenticate' => array(
'Form' => array(
'fields' => array('username' => 'email')
)
)
)
);
public function beforeFilter() {
$this->Auth->allow('index', 'view');
}
public function login() {
if ($this->request->is('post')) {
if ($this->Auth->login()) {
return $this->redirect($this->Auth->redirectUrl());
// Prior to 2.3 use
// `return $this->redirect($this->Auth->redirect());`
} else {
$this->Session->setFlash(
__('Username or password is incorrect'),
'default',
array(),
'auth'
);
}
}
}
I understand the before filter makes sense, it only allows index and view, i have another controller called admin which redirects to the login page if your not logged in
but for somme reason it keeps redirecting to users/users/login, i want it to go to users/login? How do i fix this?
you just have to put the controller wherever you go and the action
public function login() {
if ($this->request->is('post')) {
if ($this->Auth->login()) {
return $this->redirect(array('controller' => 'users', 'action' => 'login'));
}
} else {
$this->Session->setFlash(__('Invalido nombre de usuario o contraseña'));
}
}
I am writing my own Auth component for CakePHP 2, which inherit from BaseAuthenticate. This component use an external lib (located in /usr/share/php) which save information in the $_SESSION variable.
My problem is that when I change of page, all this information is removed from $_SESSION, so the external lib do not sees that I am already connected.
I tried to save the content of $_SESSION added by the lib by using $this->Session->write in Auth.MyAuthenticateComponent, but this is also removed.
Thanks for your help.
edit :
The code :
class AppController extends Controller {
public $use = array('User');
public $components = array(
'Session',
'Auth' => array(
'loginRedirect' => array('controller' => 'Sheets', 'action' => 'index'),
'logoutRedirect' => array('controller' => 'Users', 'action' => 'login')
)
);
public function beforeFilter()
{
$this->Auth->authenticate = array('Arise');
}
}
class UsersController extends AppController
{
public $helpers = array('Html', 'Form');
public function beforeFilter()
{
parent::beforeFilter();
$this->Auth->allow('login');
$this->Auth->authenticate = array('Arise');
}
public function login()
{
if ($this->request->is('post')) {
if ($this->Auth->login())
return $this->redirect($this->Auth->redirect());
else
$this->Session->setFlash('Error');
}
}
public function logout()
{
$this->redirect($this->Auth->logout());
}
}
App::uses('BaseAuthenticate', 'Controller/Component/Auth');
require_once('/usr/share/php/openid/consumer/consumer.php');
class AriseAuthenticate extends BaseAuthenticate
{
protected function _ariseAuthenticate($openid_url)
{
$consumer =& AriseOpenID::getInstance();
$required = array(
'http://somewhere/types/identifiant',
'http://axschema.org/namePerson/first',
'http://axschema.org/namePerson/friendly'
);
$consumer->setReturnTo('http://mysite/users/login');
$consumer->setTrustRoot('http://mysite/users/login');
$consumer->authenticate($openid_url, $required);
if ($consumer->isLogged()) {
$first_name = $consumer->getSingle('http://axschema.org/namePerson/first');
$nick = $consumer->getSingle('http://axschema.org/namePerson/friendly');
$id_arise = $consumer->getSingle('http://openid.iiens.net/types/identifiant');
return array(
'id_arise' => $id_arise,
'first_name' => $first_name,
'nick' => $nick
);
}
return false;
}
public function checkUser($result)
{
$User = ClassRegistry::init('User');
$result = $User->find('first', array(
'conditions' => array(
'id_arise' => $result['id_arise']
)
));
if (!$result) {
$User->create();
$User->save(array(
'id_arise' => $result['id_arise'],
'first_name' => $result['first_name'],
'nick' => $result['nick']
));
$result = $User->find('first', array(
'conditions' => array(
'id_arise' => $result['id_arise']
)
));
}
$user = $result['User'];
unset($result['User']);
return array_merge($user, $result);
}
public function authenticate(CakeRequest $request, CakeResponse $response)
{
if (!$request->is('post'))
return false;
$openid_url = (array_key_exists('login', $request->data))
? $request->data['login']['openid_url']
: NULL;
$openid_url = ($openid_url == '') ? NULL : $openid_url;
if ($result = $this->_ariseAuthenticate($openid_url))
return $this->checkUser($result);
return false;
}
public function getUser()
{
if ($result = $this->_ariseAuthenticate(NULL))
return $this->checkUser($result);
return false;
}
}
Are you unit testing your auth adapter? It is hard to tell what is wrong but I'm more or less sure authenticate() does not return the array but always false? Because if authenticate() returns valid user data it would be written to the session.
See http://api.cakephp.org/2.3/source-class-AuthComponent.html#543, that calls http://api.cakephp.org/2.3/source-class-AuthComponent.html#690 which calls all configured auth adapters. If your adapter returns an user array it should work. So I assume your adapter fails to return the array.
I have looked at quite a few similar issues on SO but none have answered my question or been able to help me resolve this... Basically when i comment out the $this->auth->allow line in the NewsController (because i only want authenticated people to access all the actions apart from login/register) it causes a login infinite loop. When i allow all users to access the index action in the newscontroller it works fine. Any ideas why this would be looping on login?
AppController
<?php
App::uses('Controller', 'Controller');
class AppController extends Controller {
public $components = array(
'Session',
'Auth' => array(
'loginAction' => array('controller' => 'users', 'action' => 'login'),
'loginRedirect' => array('controller' => 'news', 'action' => 'index'),
'logoutRedirect' => array('controller' => 'users', 'action' => 'login'),
'authorize' => array('Controller')
)
);
UsersController
<?php
class UsersController extends AppController {
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('register');
}
public function login() {
$this->layout = 'eprime_empty';
if ($this->request->is('post')) {
if ($this->Auth->login()) {
$this->redirect($this->Auth->redirect());
} else {
$this->Session->setFlash('Invalid username or password, try again', 'default', array('class' => 'warning'));
}
}
}
public function logout() {
$this->redirect($this->Auth->logout());
}
NewsController
<?php
class NewsController extends AppController {
public $helpers = array('Html', 'Form', 'Session');
public function beforeFilter() {
parent::beforeFilter();
// $this->Auth->allow('index', 'view');
}
public function index() {
$this->set('news', $this->News->find('all'));
}
If you want only authenticated peoples to get access to all action apart from login and logout then no need to define key value pair
'authorize' => array('Controller')
in AppCOntroller. Because if you specify this key, you have to specify function isAuthorized() which will return either true or false(based on condition you specify for allowing users/usergroups to access that action).
public function isAuthorized(){
return true;//or false
}
and no need to redefine
public $helpers = array('Html', 'Form', 'Session');
public $components = array('Session');
as you already defined in AppController.
There is another issue may happen when use requests actions in Elements,
so you have to allow request actions in their main Controllers as below:
--------[app\View\view.ctp]------------
$this->Element('comments');
--------[app\View\Elements\comments.ctp]----------
$comments = $this->requestAction('comments/grab');
--------[app\Controller\CommentsController]-----------
function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('grab');
}