Creating a webservice with CakePHP and AuthComponent? - php

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;
}
}

Related

fetch login user posts only

I am new in CAKEPHP and I want to fetch my post which is posted by me or login user only. How to fetch those posts? I don't have any idea.
This is the post controller code:
<?php
class PostsController extends AppController {
public $helpers = array('Html', 'Form', 'Session');
public $components = array('Session','Paginator');
public $paginate = array(
'limit' => 10,
'order' => array(
'Post.id' => 'desc'
)
);
public function index(){
$this->Paginator->settings = $this->paginate;
// Pagination Code Limit define to top
// similar to findAll(), but fetches paged results
$data = $this->Paginator->paginate();
$this->set('posts', $data);
}
public function add(){
if($this->request->is('post')){
$this->Post->create();
$this->request->data['Post']['user_id'] = $this->Auth->user('id');
if($this->Post->save($this->request->data)){
$this->Session->setFlash(__('Your Post is saved!!'));
return $this->redirect(array('action' => 'index' ));
}
$this->Session->setFlash(__('Unable to post data.'));
}
}
public function edit($id = null) {
if (!$id) {
throw new NotFoundException(__('Invalid post'));
}
$post = $this->Post->findById($id);
if (!$post) {
throw new NotFoundException(__('Invalid post'));
}
if ($this->request->is(array('post', 'put'))) {
$this->Post->id = $id;
if ($this->Post->save($this->request->data)) {
$this->Session->setFlash(__('Your post has been updated.'));
return $this->redirect(array('action' => 'index'));
}
$this->Session->setFlash(__('Unable to update your post.'));
}
if (!$this->request->data) {
$this->request->data = $post;
}
}
public function view($id = null){
if(!$id){
throw new NotFoundException(__('Invalid Post'));
}
$post = $this->Post->findById($id);
if(!$post){
throw new NotFoundException(__('Invalid Post'));
}
$this->set('post',$post);
}
public function delete($id){
if($this->request->is('get')){
throw new MethodNotAllowedException();
}
if($this->Post->delete($id)){
$this->Session->setFlash(__('Post Deleted Sucessfully!!'));
}else{
$this->Session->setFlash(
__('The post with id: %s could not be deleted.')
);
}
return $this->redirect(array('action' => 'index'));
}
}
?>
And my model is:
<?php
class Post extends AppModel {
public $validate = array(
'title' => array(
'rule'=> 'notEmpty'
),
'body' => array(
'rule'=> 'notEmpty'
)
);
}
?>
I want to fetch the posts which is posted by me or the user who are login , rather the full data.
Please help me. Thanks !
Add conditions when you are fetching the posts-
$condition = array(
'conditions' => array('posts.user_id' => $this->Auth->user('id')),
)
$this->Paginator->settings = array(
'conditions' => $conditions,
);
CakePHP Pagination
You need to make following changes in your controller to fetch your and logged in user posts
First of all add Auth component
public $components = array('Session','Paginator','Auth');
Secondly fetch your user id
$your_id (This is your user Id)
And at last your put following condition in paginator
public $paginate = array(
'limit' => 10,
'conditions' => array('posts.user_id' => $this->Auth->user('id'),'posts.user_id' => $your_id),
'order' => array(
'Post.id' => 'desc'
)
);

Authentication fails when I try to login after following the CakePHP simple authentication tutorial

I'm trying this Cake cookbook tutorial of simple authentication. Users are created successfully but when I am trying to login, it doesn't authenticate the users. Instead, shows the "Invalid username/password" error.
Only thing I have changed is that I am using the email address instead of a user name.
This is the User.php app model:
<?php
App::uses('AppModel', 'Model');
App::uses('BlowfishPasswordHasher', 'Controller/Component/Auth');
class User extends AppModel {
public $validate = array(
'email' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'An email is required'
)
),
'password' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'A password is required'
)
),
'role' => array(
'valid' => array(
'rule' => array('inList', array('admin', 'author')),
'message' => 'Please enter a valid role',
'allowEmpty' => false
)
)
);
public function beforeSave($options = array()) {
if (isset($this->data[$this->alias]['password'])) {
$passwordHasher = new BlowfishPasswordHasher();
$this->data[$this->alias]['password'] = $passwordHasher->hash(
$this->data[$this->alias]['password']
);
}
return true;
}
}
?>
This is the Users Controller (Userscontroller.php)
<?php
App::uses('AppController', 'Controller');
class UsersController extends AppController {
// public function __construct($request = null, $response = null)
// {
// parent::__construct($request, $response);
// }
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('add','logout');
}
public function index() {
$this->User->recursive = 0;
$this->set('users', $this->paginate());
}
public function view($id = null) {
$this->User->id = $id;
if (!$this->User->exists()) {
throw new NotFoundException(__('Invalid user'));
}
$this->set('user', $this->User->read(null, $id));
}
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'));
}
$this->Session->setFlash(
__('The user could not be saved. Please, try again.')
);
}
}
public function edit($id = null) {
$this->User->id = $id;
if (!$this->User->exists()) {
throw new NotFoundException(__('Invalid user'));
}
if ($this->request->is('post') || $this->request->is('put')) {
if ($this->User->save($this->request->data)) {
$this->Session->setFlash(__('The user has been saved'));
return $this->redirect(array('action' => 'index'));
}
$this->Session->setFlash(
__('The user could not be saved. Please, try again.')
);
} else {
$this->request->data = $this->User->read(null, $id);
unset($this->request->data['User']['password']);
}
}
public function delete($id = null) {
// Prior to 2.5 use
// $this->request->onlyAllow('post');
$this->request->allowMethod('post');
$this->User->id = $id;
if (!$this->User->exists()) {
throw new NotFoundException(__('Invalid user'));
}
if ($this->User->delete()) {
$this->Session->setFlash(__('User deleted'));
return $this->redirect(array('action' => 'index'));
}
$this->Session->setFlash(__('User was not deleted'));
return $this->redirect(array('action' => 'index'));
}
public function login() {
if ($this->request->is('post')) {
if ($this->Auth->login()) {
return $this->redirect($this->Auth->redirectUrl());
}
$this->Session->setFlash(__('Invalid username or password, try again'));
}
}
public function logout() {
return $this->redirect($this->Auth->logout());
}
}
?>
This is login.ctp view:
<div class="users form">
<?php echo $this->Session->flash('auth'); ?>
<?php echo $this->Form->create('User'); ?>
<fieldset>
<legend>
<?php echo __('Please enter your username and password'); ?>
</legend>
<?php echo $this->Form->input('email');
echo $this->Form->input('password');
?>
</fieldset>
<?php echo $this->Form->end(__('Login')); ?>
</div>
This is the Appcontroller.php
<?php
/**
* Application level Controller
*
* This file is application-wide controller file. You can put all
* application-wide controller-related methods here.
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* #copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* #link http://cakephp.org CakePHP(tm) Project
* #package app.Controller
* #since CakePHP(tm) v 0.2.9
* #license http://www.opensource.org/licenses/mit-license.php MIT License
*/
App::uses('Controller', 'Controller');
/**
* Application Controller
*
* Add your application-wide methods in the class below, your controllers
* will inherit them.
*
* #package app.Controller
* #link http://book.cakephp.org/2.0/en/controllers.html#the-app-controller
*/
class AppController extends Controller {
//...
public $components = array(
'Session',
'Auth' => array(
'loginRedirect' => array(
'controller' => 'sites',
'action' => 'index'
),
'logoutRedirect' => array(
'controller' => 'pages',
'action' => 'display',
'home'
),
'authenticate' => array(
'Form' => array(
'passwordHasher' => 'Blowfish'
)
)
)
);
public function beforeFilter() {
$this->Auth->allow('index', 'view');
}
//...
}
Edit Following line in you Appcontroller.php as mention below
'Form' => array(
'passwordHasher' => 'Blowfish',
'fields' => array('username'=>'email', 'password'=>'password'),
)

Cakephp Auth Redirect

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'));
}
}

Auth Component not logging in users

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

CakePHP: saving information in session

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.

Categories