DarkAuth - another way...
I wrote this initially for Cake 1.1 - basing it on ideas from "obAuth" by Steve Oliveira, but upgraded it to 1.2 rather than using the built in Auth component, mostly because this works how I want it to and, once setup, is really easy to use.
Main Features:
- Per action / per controller / inline access control
- Optional Group support for HABTM and User BelongsTo Group associations
- A "super-user" functionality allowing one group automatic access granted
- Optional tamper-proof Cookie support
- Custom password hashing to suit your Model
I'm fairly new to CakePHP and I went for the stable release, and immediately wanted to do User Authentication. It's almost the first thing I build into any project. CakePHP 1.1 didn't have it, so I built my own.
This is mainly based on "obAuth" by Steve Oliveira. It was those ideas that formed the basis for this component. It includes a lot of the functionality that was designed into obAuth but never completed and also now ammended to work with CakePHP 1.2.
As soon as I switched to CakePHP 1.2 and wanted the same great features I built into the original and the same easy access control. So, I rewrote it and here's the result.
Firstly I'll show you how easy it is to work with.
Let's say you have a SecretsController which you want to restrict access to:
Notice the one-liner? This will restrict access to the controller to Users who are memebrs of either the group 'Secret Keepers' or the group 'Super Cool People'.
Easy huh? However, I think Cake's own is that easy as well, so lets look at some more functionality.
How about you have a DocumentsController that only certain people can add to?
Now that was easy, only memebers of the group 'Secret Makers' will have access.
How about your DocumentsController that has some Top Secret stuff in it and you want to restrict access? We could add to our "view" action some simple code:
Note that the function "requiresAuth()" stops processing after you call it and will bring up an "access denied" view if authentication fails.
What if you wanted not to fail after but to redirect somewhere else?
Or more common if you wanted to show content based on whether authentication was present?
The "isAllowed()" function will return true/false but not halt processing.
The final selling point (in my opinion)! $DarkAuth_User available in the View, automatically populated with the user info from the user model. e.g.
Yields (if logged in, if not logged in the variable is null):
Which means you can do this:
Convinced? I hope so. Now on the Code and Setup
This is mainly based on "obAuth" by Steve Oliveira. It was those ideas that formed the basis for this component. It includes a lot of the functionality that was designed into obAuth but never completed and also now ammended to work with CakePHP 1.2.
As soon as I switched to CakePHP 1.2 and wanted the same great features I built into the original and the same easy access control. So, I rewrote it and here's the result.
Firstly I'll show you how easy it is to work with.
Let's say you have a SecretsController which you want to restrict access to:
Controller Class:
<?php
class SecretsController extends AppController {
var $name = 'Secrets';
var $DarkAuth_requiresAuth = array('Secret Keepers','Super Cool People');
...
}
?>
Notice the one-liner? This will restrict access to the controller to Users who are memebrs of either the group 'Secret Keepers' or the group 'Super Cool People'.
Easy huh? However, I think Cake's own is that easy as well, so lets look at some more functionality.
How about you have a DocumentsController that only certain people can add to?
Controller Class:
<?php
class DocumentsController extends AppController {
var $name = 'Documents';
function add(){
$this->DarkAuth->requiresAuth = array('Secret Makers');
...
}
...
}
?>
Now that was easy, only memebers of the group 'Secret Makers' will have access.
How about your DocumentsController that has some Top Secret stuff in it and you want to restrict access? We could add to our "view" action some simple code:
Controller Class:
<?php
function view($id){
$this->Document->id = $id;
$doc = $this->Document->read();
if($doc['Document']['top_secret'] == true){
$this->DarkAuth->requiresAuth('Top Brass');
}
...
}
?>
Note that the function "requiresAuth()" stops processing after you call it and will bring up an "access denied" view if authentication fails.
What if you wanted not to fail after but to redirect somewhere else?
Controller Class:
<?php
$this->DarkAuth->requiresAuth('Top Brass');
?>
Or more common if you wanted to show content based on whether authentication was present?
Controller Class:
<?php
if($this->DarkAuth->isAllowed(array('Chocolate Lover'))){
$data = $this->CookieJar->findAll(array('Chocolate'=>true));
}else{
$data = $this->CookieJar->findAll(array('Chocolate'=>false));
}
?>
The "isAllowed()" function will return true/false but not halt processing.
The final selling point (in my opinion)! $DarkAuth_User available in the View, automatically populated with the user info from the user model. e.g.
View Template:
pr($DarkAuth_User);
Yields (if logged in, if not logged in the variable is null):
array(
'id' => 1
'username' => "superstar"
'password' => "abcdef1234567890abcdef1234567890"
'other_info' => "Some data"
)
Which means you can do this:
View Template:
if(!empty($DarkAuth_User)){
echo "Some content for logged in people!";
}
Convinced? I hope so. Now on the Code and Setup
So here's the code for the component, it's quite a chunk, then on the next page I'll describe the setup.
Component Class:
<?php
class DarkAuthComponent extends Object {
var $user_model_name = 'User';
var $users_controller_name = 'Users';
var $user_name_field = 'email'; //e.g. email or firstname or username...
var $user_name_case_folding = 'lower'; //do you want to case fold the username before verifying? either 'lower','upper','none', to change case to lower/upper/leave it alone before matching.
var $user_pass_field = 'password';
var $user_live_field = 'live'; // surely you have a field in you users table to show whether the user is active or not? set to null if not.
var $user_live_value = 1;
var $group_model_name = 'Group'; //Group for access control if used. NB: DON'T CALL requiresAuth with Groups if no group model. it will error.
var $group_name_field = 'name'; // the name of the field used for the groups name. This will be used to check against passed groups.
var $HABTM = true; //set to false if you don use a HABTM group relationship.
var $superuser_group = 'Root'; //if you want a single group to have automatically granted access to any restriction.
var $login_view = '/login'; //this is the login view, usually {user_controller}/login but you may have changed the routes.
var $deny_view = '/deny'; //this is the default denied access view.
var $logout_page = '/'; // NB this is were to redirect AFTER logout by default
var $login_failed_message = '<p class="error">Login Failed, Please check your details and try again.</p>'; //This message is setFlash()'d on failed login.
var $allow_cookie = true; //Allow use of cookies to remember authenticated sessions.
var $cookie_expiry = '+6 Months'; //how long until cookies expire. format is "strtotime()" based (http://php.net/strtotime).
//var $session_secure_key = 'sRmtVStkedAdlxBy'; //some random stuff that someone is unlikey to guess.
var $session_secure_key = 'sJfkgD420YsfhC2k4Abs';
/*
* You can edit this function to explain how you want to hash your passwords.
*/
function hasher($plain_text){
$hashed = md5('dark'.$plain_text.'cake');
return $hashed;
}
##########################################################################
/*
* DON'T EDIT THESE OR ANYTHING BELOW HERE UNLESS YOU KNOW WHAT YOU'RE DOING
*/
var $controller;
var $here;
var $components=array('Session');
var $current_user;
var $from_session;
var $from_post;
var $from_cookie;
function startup(&$controller){
//Let's check they have changed the secure key from the default.
if($this->session_secure_key == 'sRmtVStkedAdlxBy'){
die('<p>Please change the DarkAuth::session_secure_key value from it default.</p>');
}
$this->controller = $controller;
$this->here = substr($controller->here,strlen($controller->base));
$this->controller->_login();
//now check session/cookie info.
$this->getUserInfoFromSessionOrCookie();
//now see if the calling controller wants auth (except for the users/login or logout or deny actions)
if( array_key_exists('DarkAuth_requiresAuth', $controller) ){
// We want Auth for any action here
if(array_key_exists('DarkAuth_ifAccessDenied',$controller)){
$deny = $controller->DarkAuth_ifAccessDenied;
}else{
$deny = null;
}
$this->requiresAuth($controller->DarkAuth_requiresAuth,$deny);
}
//finally give the view access to the data
$this->controller->set('DarkAuth_User',$this->getUserInfo());
}
function secure_key(){
static $key;
if(!$key){
$key = md5(Configure::read('Security.salt').'!DarkAuth!'.$this->session_secure_key);
}
return $key;
}
function requiresAuth($groups=array(),$deny_redirect=null){
if( empty($this->current_user) ){
// Still no info! render logion page!
if($this->from_post){
$this->Session->setFlash($this->login_failed_message);
}
$this->controller->render($this->login_view);
exit();
}else{
if($this->from_post){
// user just authed, so redirect to avoid post data refresh.
$this->controller->redirect($this->here);
exit();
}
// User is authenticated, so we just need to check against the groups.
if( empty($groups) ){
// No Groups specified so we are good to go!
$deny = false;
}else{
$deny = !$this->isAllowed($groups);
}
if($deny){
// Current User Doesn't Have Access! DENY
if($deny_redirect){
$this->controller->redirect($deny_redirect);
exit();
}else{
$this->controller->render($this->deny_view);
exit();
}
}
}
return true;
}
function isAllowed($groups=array()){
if( empty($this->current_user) ){
// No information about the user! FALSE
return false;
}else{
// User is authenticated, so we just need to check against the groups.
if(!is_array($groups)){ $groups[0] = $groups; }
if( empty($groups) ){
// No Groups specified so we are good to go! TRUE
return true;
}else{
//first check superuser access.
if($this->superuser_group){
array_unshift($groups,$this->superuser_group);
}
// Check each group.
if(!$this->HABTM){
// Single relation ship.
foreach($groups as $g){
if(
$this->current_user[$this->group_model_name]['id'] == $g ||
$this->current_user[$this->group_model_name][$this->group_name_field] == $g
){
// Our Authenticated user matches a group! TRUE
return true;
}
}
}else{
//HasAndBelongToMany relationship. we search the other way around...
foreach($this->current_user[$this->group_model_name] as $g){
if(
in_array($g['id'],$groups) ||
in_array($g[$this->group_name_field],$groups)
){
// Our Authenticated user matches a group! TRUE
return true;
}
}
}
//No Access this time. FALSE
return false;
}
}
}
function getCookieInfo(){
if(!array_key_exists('DarkAuth',$_COOKIE)){
//No cookie
return false;
}
list($hash,$data) = explode("|||",$_COOKIE['DarkAuth']);
if($hash != md5($data.$this->secure_key())){
//Cookie has been tampered with
return false;
}
$crumbs = unserialize(base64_decode($data));
if(!array_key_exists('username',$crumbs) ||
!array_key_exists('password',$crumbs) ||
!array_key_exists('expiry' ,$crumbs)){
//Cookie doesn't contain the correct info.
return false;
}
if(!isset($crumbs['expiry']) || $crumbs['expiry'] <= time()){
//Cookie is out of date!
return false;
}
//All checks passed, cookie is genuine. remove expiry time and return
unset($crumbs['expiry']);
return $crumbs;
}
function setCookieInfo($data,$expiry=0){
if($data === false){
//remove cookie!
$cookie = false;
$expiry = 100; //should be in the past enough!
}else{
$serial = base64_encode(serialize($data));
$hash = md5($serial.$this->secure_key());
$cookie = $hash."|||".$serial;
}
if($_SERVER['SERVER_NAME']=='localhost'){
$domain = null;
}else{
$domain = '.'.$_SERVER['SERVER_NAME'];
}
return setcookie('DarkAuth', $cookie, $expiry, $this->controller->base, $domain);
}
function authenticate_from_post($data){
$this->from_post = true;
return $this->authenticate($data);
}
function authenticate_from_session($data){
$this->from_session = true;
return $this->authenticate($data);
}
function authenticate_from_cookie(){
$this->from_cookie = true;
return $this->authenticate($this->getCookieInfo());
}
function authenticate($data){
if($data === false){
$this->destroyData();
return false;
}
if($this->from_session || $this->from_cookie){
$hashed_password = $data['password'];
}else{
$hashed_password = $this->hasher($data['password']);
}
switch($this->user_name_case_folding){
case 'lower':
$data['username'] = strtolower($data['username']);
break;
case 'upper';
$data['username'] = strtoupper($data['username']);
break;
default: break;
}
$conditions = array(
$this->user_model_name.".".$this->user_name_field => $data['username'],
$this->user_model_name.".".$this->user_pass_field => $hashed_password
);
if($this->user_live_field){
$field = $this->user_model_name.".".$this->user_live_field;
$conditions[$field] = $this->user_live_value;
};
$check = $this->controller->{$this->user_model_name}->find($conditions);
if($check){
$this->Session->write($this->secure_key(),$check);
if(
$this->allow_cookie && //check we're allowing cookies
$this->from_post && //check this was a posted login attempt.
array_key_exists('remember_me',$data) && //check they where given the option!
$data['remember_me'] == true //check they WANT a cookie set
){
// set our cookie!
if(array_key_exists('cookie_expiry',$data)){
$this->cookie_expiry = $data['cookie_expiry'];
}else{
$this->cookie_expiry;
}
if(strtotime($this->cookie_expiry) <= time()){
// Session cookie? might as well not set at all...
}else{
$expiry = strtotime($this->cookie_expiry);
$this->setCookieInfo(array('username'=>$data['username'], 'password'=>$hashed_password, 'expiry'=>$expiry), $expiry);
}
}
$this->current_user = $check;
return true;
}else{
$this->destroyData();
return false;
}
}
function getUserInfo(){
return $this->current_user[$this->user_model_name];
}
function getAllUserInfo(){
return $this->current_user;
}
function destroyData(){
$this->Session->delete($this->secure_key());
if($this->allow_cookie){
$this->setcookieInfo(false);
}
$this->current_user = null;
}
function logout($redirect=false){
$this->destroyData();
if(!$redirect){
$redirect = $this->logout_page;
}
$this->controller->redirect($redirect);
exit();
}
function getUserInfoFromSessionOrCookie(){
if( !empty($this->current_user) ){
return false;
}
if($this->Session->valid() && $this->Session->check($this->secure_key()) ){
$this->current_user = $this->Session->read($this->secure_key());
return $this->authenticate_from_session(array(
'username' => $this->current_user[$this->user_model_name][$this->user_name_field],
'password' => $this->current_user[$this->user_model_name][$this->user_pass_field],
));
}elseif($this->allow_cookie){
return $this->authenticate_from_cookie();
}
}
}
?>
Got all that... good now let's set it up!
The follow steps should guide you through the setup process and the files you need to alter.
Of course, you will need to have the models for your User table (and groups if applicable).
I would often use the following with a $hasAndBelongsToMany association (I pretty much always use the first 4 fields of the users and groups tables with cake):
CREATE TABLE `users` (
`id` int(11) NOT NULL auto_increment,
`created` datetime default NULL,
`modified` datetime default NULL,
`live` tinyint(1) NOT NULL default 0,
`username` varchar(16) NOT NULL default '',
`password` varchar(32) NOT NULL default '',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `groups` (
`id` int(11) NOT NULL auto_increment,
`created` datetime default NULL,
`modified` datetime default NULL,
`live` tinyint(1) NOT NULL default 0,
`name` varchar(32) NOT NULL default '',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `groups_users` (
`group_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
KEY `group_id` (`group_id`,`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Look at the Cake Manual for how to setup the Models for these tables.
If you don't use the HABTM association, then remember to set var HABTM = false; later. This will then assume that the user $belongsTo a group (and therefore you'd need a "group_id" field in your "users" table).
Now we have 5 (or 6) steps to a working, powerful authentication system!
Step 1: Modify AppController
I decided this was the easiest way as then your whole site knows about the Authentication, however I can see how it might put unnecessary load on in some situations.
This allows all controllers/views access to the auth component/data. In app_controller.php:
Controller Class:
<?php
class AppController extends Controller {
var $uses = array ('YOUR_MODEL_FOR_USERS');
var $components = array('DarkAuth');
}
?>
Where YOUR_MODEL_FOR_USERS is the name of your user model.
NB Remember if you want to use controllers with no models you will now need to use var $uses = array(); rather than var $uses = null; or you'll get errors!
Step 2: Add Default Methods
Now add the inversal login/logout methods to your app_controller.php and auto-include the "Session" helper (or is that included by default anyway now...):
Controller Class:
<?php
var $helpers = array('Session');
function _login(){
if($this->data['DarkAuth']){
unset($this->data['from_session']);
$this->DarkAuth->authenticate_from_post($this->data['DarkAuth']);
exit();
}
}
function logout(){
$this->DarkAuth->logout();
// By this stage we should have redirected and exited already, but just in case we'll pass them back to home...
$this->redirect($this->referer()); //thanks to everyone who spotted this.
}
?>
NB the logout method is called "logout" meaning you can call it from any controller at "/:controller/logout" but "_login()" won't be available, meaning you can create your own login page in a controller/page.
Step 3: Add the Views
Now we need to add the views for this component. They should be in the root of you views folder as we will need to call them from arbitrary controllers.
The 2 files are totally up to you except that the login page must pass the following data in the form:
[DarkAuth][username],
[DarkAuth][password]
and optionally if you have set the "$allow_cookie" variable:
[DarkAuth][remember_me],
[DarkAuth][cookie_expires],
Here are the templates I use:
View Template:
<?php /* View for login.ctp */ ?>
<h2>Login</h2>
<div id='loginbox'>
<?php
echo $form->create('DarkAuth',array('url'=>substr($this->here,strlen($this->base))));
echo "\n<div class='input required'>";
echo $form->input('username', array('div'=>false));
echo "</div>";
echo "\n<div class='input required'>";
echo $form->label('password');
echo $form->password('DarkAuth/password');
echo "</div>\n";
/* if you want to use cookies uncomment this. */
/*
echo "<div class='input required'>";
echo $form->checkbox('DarkAuth/remember_me');
echo $form->label('Remember Me? (uses cookies)');
echo "</div>\n";
echo "<div class='input required'>";
echo $form->label('If so, for how long?');
echo $form->select('DarkAuth/cookie_expiry',array(
'+1 week'=>'in a week',
'+1 Months'=>'in a month',
'+6 Months'=>'in 6 months',
));
echo "</div>\n";
/* end of cookie bits */
echo $form->end('Login');
?>
</div>
<?php /* View for deny.ctp */ ?>
<h2>Access Denied</h2>
<p>Sorry you don't have sufficient permission to access this page!</p>
Step 4: Edit the Component Setup Variables
Edit the class variables in this file to match your model structure.
these are in the top of the class definition on the previous page.
Step 5: Customise the password hasher
Change the "hasher()" function to match the way you store passwords in your model.
By default the hasher simply md5 hashes the input. you may wish to add salt, or encrypt in a different way.
Step 6 (optional): Create a Logout Route
Set up a route in you routes.php to allow you to logout in a nice way. Otherwise, you need to call "/controller/logout". I personally usually use my "Users" controller for this.
Router::connect('/logout', array('controller' => 'ANY_CONTROLLER', 'action' => 'logout'));
And that's all
It sounds like a lot when I write it down, but actually it's not hard and the effect is great and easy to use. I haven't looked at Cake's own to know whether this is better / worse , simpler / more complex but it works for me and perhap you need something exactly like this!

I am using CakePHP 1.2 RC 3 and downloaded the test application from: http://thechriswalker.net/files/DarkAuth.test.app.zip
I allthough tried adding
$this->redirect('./');to the function _login() in app_controler.phpAny Ideas?
STEP [ 1 ] Create 3 tables, if you have users table just add this fields (live, username, password)
CREATE TABLE `users` (
`id` int(11) NOT NULL auto_increment,
`created` datetime default NULL,
`modified` datetime default NULL,
`live` tinyint(1) NOT NULL default 0,
`username` varchar(16) NOT NULL default '',
`passwd` varchar(32) NOT NULL default '',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `groups` (
`id` int(11) NOT NULL auto_increment,
`created` datetime default NULL,
`modified` datetime default NULL,
`live` tinyint(1) NOT NULL default 0,
`name` varchar(32) NOT NULL default '',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `groups_users` (
`group_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
KEY `group_id` (`group_id`,`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
STEP [ 2 ] Create Group Model (/app/models/group.php)
Model Class:
<?php
class Group extends AppModel {
var $name = 'Group';
var $useTable = 'groups';
}
?>
STEP [ 3 ] Add HABTM to your user's model (/app/models/user.php)
var $hasAndBelongsToMany = array('Group' => array('className' => 'Group',
'joinTable' => 'groups_users',
'foreignKey' => 'user_id',
'associationForeignKey'=> 'group_id',
'unique' => true
)
);
STEP [ 4 ] Modify your appcontroller like mine (/app/app_controller.php)
Controller Class:
<?php
class AppController extends Controller {
var $helpers = array('Form', 'Html', 'Javascript', 'Session');
var $uses = array('User', 'Group');
var $components = array('DarkAuth');
function _login(){
if(is_array($this->data) && array_key_exists('DarkAuth',$this->data) ){
$this->DarkAuth->authenticate_from_post($this->data['DarkAuth']);
$this->data['DarkAuth']['password'] = '';
}
}
function logout(){
$this->DarkAuth->logout();
}
}
?>
STEP [ 5 ] Put DarkAuth Component as (/app/controllers/components/dark_auth.php)
You can get the code from author site http://thechriswalker.net/darkauth-2
Component Class:
<?phpclass DarkAuthComponent extends Object {
....
}
?>
STEP [ 6 ] Add some view (/app/views/login.ctp)
View Template:
and (/app/views/deny.ctp)<?
$this->pageTitle = 'Access Restricted';
echo $form->create('DarkAuth',array('url'=>substr($this->here,strlen($this->base))));
echo $form->input('DarkAuth.username');
echo $form->password('DarkAuth.password');
echo $form->end('login');
?>
View Template:
<?php
$this->pageTitle = 'Access Denied!';
?>
<p>I'm sorry, but you don't have sufficient permission to access this page!</p>
and then modify (/app/controllers/components/dark_auth.php) to match your password encryption type.
find "function hasher".
in this default hasher your password should befunction hasher($plain_text){
$hashed = md5('dark'.$plain_text.'cake');
return $hashed;
}
UPDATE users SET password = MD5('dark....cake') WHERE id = ....
find "$user_name_field" and set variable as your table's field
because we use 'username' and 'password' from CREATE TABLE above, so we have to set like this :var $user_name_field = 'email';
var $user_pass_field = 'pswd';
var $user_name_field = 'username';
var $user_pass_field = 'passwd';
STEP [ 7 ] Add new records to your table
INSERT INTO `groups` (`created`, `modified`, `live`, `name`) VALUES
(NOW(), NOW(), 1, 'Admin'),
(NOW(), NOW(), 1, 'Root');
INSERT INTO `groups_users` (`group_id`, `user_id`) VALUES
(1, 1);
INSERT INTO `users` (`live`, `username`, `passwd`) VALUES
('1', 'YOURNAME', MD5('darkMYPASSWORDcake'));
STEP [ 8 ] Put any rules in your controller
var $_DarkAuth = array('required'=>array('Admin','Member'));
eg : in my User controller
Controller Class:
<?php
class UsersController extends AppController {
var $name = 'Users';
var $helpers = array('Html', 'Form');
var $_DarkAuth = array('required'=>array('Admin','Member'));
...
...
}
?>
STEP [ 9 ] Testing go to http://yourapps/users/login, type YOURNAME as username
and MYPASSWORD as password.
Happy coding...thanks to Chris
To fix this, replace:
$this->Session->destroy($this->secure_key());
by
$this->Session->delete($this->secure_key());
Thanks, I've updated this in the article. Also I have updated the code in a much bigger way, adding some new features and improving efficiency, and have posted a new article with it - which hasn't been moderated yet. Sometime soon it should be available at: http://bakery.cakephp.org/articles/view/darkauth-v1-3-an-auth-component
Hi Chris, any ideas when the article might be moderated? I am quite interested in the updated code for my new project :)
I have no idea, so I put a copy of the article on my own website... http://thechriswalker.net/darkauth-1. Enjoy.
In response to Stefano Pallicca:
It looks like you haven't added the
$uses = array('User');
line to your AppController, that's what I would check first.
The controller your home.ctp view uses is the PagesController, which doesn't appear to have access to your User model. In an update I will get DarkAuth to load it automagically if needed, but for now you must add it to your AppController class.
That was the point: I added 'user' (lowercase), that's why it didn't work! Thanks for the tip and keep improving darkauth!
I'll try to describe my problem more in depth: I've successfully applied darkauth to a User model, so if I try to access /cake/users I get my login screen, and everything works fine.
Now, if I want to go back to my site homepage, located in /cake, I get an error:
Undefined property: PagesController::$User [APP/controllers/components/dark_auth.php, line 248]
Line 248 says:
$check = $this->controller->{$this->user_model_name}->find($conditions);
And I can understand the error, since home.ctp has no controller associated.
home.ctp shows correctly if I logout from darkauth...
What if I'd like to show a different content on the home page for logged/unlogged users? Is it possibile?
Thanks in advance and sorry for the long post.
I followed all your steps and am using your login and deny pages. DarkAuth is protecting a test controller, but after completing the login form I am not getting the page of the controller action. All I get is the Debug info, which is shown at the bottom of the page with the CakePHP default views. After reloading or loading another action manually, I get the correct behavior.
As I have by now started with freshly baked controllers/views a couple of times I begin to wonder whether this is an Apache or DarkAuth problem.
Any ideas?
Thanks for the nice component!
I had the same problem, I found a workaround by removing the line
exit();
from the _login() function in app_controller.php and sobstituting it with:
$this->redirect('./');
Hope that works
First, I would like to thank Chris Walker or this wonderful component. It is simple, straightforward and fully working.
My approach to the problem above is to include this line:
$this->redirect($this->referer());
just before the exit();
This way, the user is redirected to the url he wants to.
We are all newbies once and I know exactly how you feel, when I first started I was completely lost (coming from an ASP.NET background to PHP), but it is through the docs and articles like these that I have quickly picked it up.
As far as the problems you have, the SQL error means you have not created the correct columns in your table.
"Look at the Cake Manual for how to setup the Models for these tables." - Means just that - go check out the documentation and samples that are available and you will quickly see how to implement the models for your application.
Anyways, I for one would like to say thank you to the author, I am in the middle of implementing this in my current project and it's looking promising. Great job
I'm newbie in cakePHP and I think this article is written in very bad way. Why you didn't create COMPLETE GUIDE ? You wrote sentenses like: "Look at the Cake Manual for how to setup the Models for these tables.", "var $uses = array ('YOUR_MODEL_FOR_USERS'); ", and so on.
I'm newbie and I don't know what you mean. I looked at manual but it still doesn't work !!!
I have errors like : "SQL Error: 1054: Unknown column 'User.email' in 'where clause'", when I go to "cake_1.2beta/users/_login" it has error "Error: UsersController::_login() cannot be accessed directly.", and so on ...
I know that I mistakely did something, BUT YOU CAN WRITE ARTICLES MORE UNDERSTAND ...
What do you recommend me ?
thx
However the one thing that will probably keep me from using it, is that my tastes are a bit opposite to yours. I prefer to define access names and check for those. I have predefined what access the groups have and check if a user has access through it's group.
I dont know if that is clear, but in your example, I would define that the SecretsController requires "Secret level access" and either the (or one of the) group that logged in user belongs to has access to it or not.
The gain from doing it this way is that I don't have to edit my secrets controller when adding,removing or editing groups . This I feel is more inline with the cake behavior of controllers.
Anyways, just wanted to offer my 2 cents and thank you for your contribution.