zen of coding

User Auth with CakePHP 2.1 – part 3

As promised in the previous part we’ll take a look at the admin section.

If you remember, we’ve setup our users so that when they create an account, they are inactive by default and cannot login into the app.

app/Controller/AppController.php

$this->Auth->authenticate = array(
            'all' => array (
                'scope' => array('User.is_active' => 1)
            ),
            'Form'
        );

Since our freshly created users have is_active = 0 we’ll need to create an admin page where one would be able to approve inactive users.
Let’s see how we’ll act in the admin role.

In part 1, we’ve setup prefix routing and our app is ready to accept admin logins.
This is our login() method again:

public function login() {
            if ($this->request->is('post')) {
                if ($this->Auth->login()) {
                    if ($this->Auth->user('is_admin')) {
                        return $this->redirect(array(
                            'controller' => 'users',
                            'action' => 'index',
                            'admin' => true
                        ));
                    } else {
                        return $this->redirect('/');
                    }
                } else {
                    $this->Session->setFlash(__('Username or password is incorrect'), 'default', array(), 'auth');
                }
            }
        }

And here’s a relevant view, just in case:

<?php
    echo $this->Form->create();
    echo $this->Form->inputs(
        array(
            'username',
            'password'
        )
    );
    echo $this->Form->end('Submit');
    echo $this->Html->link('Don\'t have an account? Register now!', array(
        'controller' => 'users',
        'action' => 'add'
    ));
?>

If we look at the redirect() method in the above login() it presumes that we have an admin_index() action.
Let’s create one:

public function admin_index() {
            $users = $this->paginate($this->User, array(
                'User.is_active' => 0
            ));
            $this->set(compact('users'));
        }

The goal is to display (paginate) inactive users, so that an admin can approve them… simple enough.
I’m not going to cover pagination setup here, as it is very simple, covered nicely in the manual and would be beyond what we need consider for now.

Anyways, let’s build a simple view to display our inactive users:

<?php if (isset($users) && !empty($users)) : ?>
   <?php foreach ($users as $user) : ?>
    <div>
        <?php echo $user['User']['username']; ?>
        <?php
            echo $this->Html->link('Activate', array(
                'controller' => 'users',
                'action' => 'user_activate',
                'admin' => true,
                 $user['User']['id']
            ));
        ?>
        <?php
            echo $this->Html->link('Edit', array(
                'controller' => 'users',
                'action' => 'user_edit',
                'admin' => true,
                 $user['User']['id']
            ));
        ?>
    </div>
   <?php endforeach; ?>
<?php endif; ?>

Next to each username we’ll show an “Activate” and “Edit” links.
Ultimately the “Activate” link we’ll be something like example.com/admin/users/user_activate/345. This should change the user status with ID = 345 from inactive to active.
Here’s the method to do so:

public function admin_user_activate($id = null) {
            if ($id) {
                $this->User->id = $id;
                if ($this->User->saveField('is_active', 1)) {
                    return $this->redirect(array(
                        'controller' => 'users',
                        'action' => 'index',
                        'admin' => true
                    ));
                }
               
            }
        }

All we are doing is updating is_active field to “1” for a given user $id.
Now the user has been approved and we redirect the admin back to the index page.

Let’s recap:

  1. We’ve setup basic Auth to allow users to login and register in the system
  2. We’ve added a check so that only active users can login
  3. We’ve setup admin/prefix routing to allow for creation of admin-only resources
  4. We’ve added a check so that only admins can access the above resources
  5. And finally, we’ve added the ability for admins to activate the users

p.s. Here’s a simple chunk of code that creates a “Log in/Log out” link so that users can act accordingly. You’ll probably want to add this to your layout or a relevant element.

<?php
echo $this->Session->check('Auth.User')
?
$this->Html->link(
             'Log out',
              array(
                 'controller' => 'users',
                 'action' => 'logout',
                 'admin' => false
              ))
:
$this->Html->link(
              'Log in',
               array(
                  'controller' => 'users',
                  'action' => 'login'
               ));
?>

With a simple check for presence of the Auth.User key (this is where Auth stores information about logged-in users) we know if the user is logged-in or not into the system, and by using a quick ternary operator we display either a “Log out” or “Log in” links.

The end.

  • This is great. Have you thought about writing a book?

  • Practitioner

    Wonderful, a great start, could you please provide a link to the final source of this tutorial?

  • teknoid

    @Eric Hamilton

    I have, but never got around to making it actually happen. Also, CakePHP grows rather fast, so that most books on it become outdated before they get released.

    @Practitioner

    As far as user authentication, this is the complete code. The rest of your system will be really dependent on your specific needs, and for this sample it wouldn’t be helpful to add any other code, as I wanted to keep it generic as much as possible.

  • claudi

    hi there, i’don’t wheter you still read the comments in here, but i give it a try.
    i’ve been walked through this tutorial, and everythings works fine, except the thing that a normal activated user can’t login..can’t figure out what the problem is, neither where i can fix it

    • teknoid_cakephp

      I would start by looking at your SQL debug and making sure the query is working as expected. (i.e. the hash is right and the is_active flag is set, etc.)

  • marksie1988

    im a bit confused with this as the tutorial doesnt explain which files to put the code in like you have in the previous tutorials. makes it difficult for someone who is learning

%d bloggers like this: