Kohana 3 auth: sample implementation and documentation

This is the 3rd part of my mini-series on Kohana 3 auth. I figure the best way to show the Kohana Auth module works is to provide a sample application module which uses auth. In this series of posts, I discuss:

  1. Setting up the basic Auth in KO3 (part 1)
  2. An overview of the functionality provided by the Auth module (part 2)
  3. Tips on implementing Auth in a custom application (part 3; this part)
  4. Getting started with Useradmin, my Kohana 3 auth admin module (part 4)

The new release is AWESOME :) , and now is based on the Kohana 3.1.x API. (You can get the old version for 3.0.x via Github.)

Here are a few screenshots:


New UI, more providers supported! Get it from:

This is a custom module, and the code is in /modules/user. The code contains way more comments than usual. I’ve tried to make things clear, and keep the UI basic but pretty enough.

Further, the code is released under the BSD licence, so you can use it in commercial applications. While I don’t restrict you in using the code, it is good karma to send improvements to this module back: in particular, I would like to have the features in the roadmap below.

What functionality is there:

  • Use the base Ko3 auth module and do not reinvent the wheel — OK
  • Support translation; no strings without __() — OK
  • Boilerplate for administration (create user, edit user, delete user, list users and last logins) — OK; roles have to be added via DB but that’s OK
  • Boilerplate for users (login, logout, view profile, edit profile, unregister, access denied page; error handling/validation) — OK
  • reCAPTCHA optionally supported for registration — OK; implemented for registration, thank you jnbdz!
  • Optional support for 3rd party login:
    • Facebook — OK
    • Google — OK
    • Yahoo — OK
    • Twitter — OK (with the caveat that Twitter does not allow you to get the email address via api)
  • Login  using username, email or both — OK
  • Optional lost password reset via email — OK; workflow is a bit clunky (user has to type the new password one time)
  • Optional autologin support via cookies — OK but not documented here; read about it Ko3 docs. Need to add checkbox to UI.
  • Optional enforcement of number of failed login attempts — is there but configuration/activation is clunky.
  • UI design that doesn’t make your eyes bleed — OK
  • Kohana 3.1.x support – OK, thank you gartz!

What needs to be done – contribute this!

  • reCAPTCHA optionally supported for too many failed logins
  • Optional account activation via confirmation email + expire unactivated account/welcome message via email
  • Optional password strength indicator for client
  • Separation between module and sample app on Github — e.g. migrate development to Github only

Nice-to-have (perhaps release as compatible modules?)

  • Profile picture loading from Facebook, Twitter or uploaded image — not yet.

So if you implement any of those, and don’t it to be too much of a burden to publish them under the BSD licence, let me know via comments or via email (firstname.surname@gmail.com).

Changelog is in the readme file on Github/Bitbucket.

Useful code snippets

Here are some code snippets which show you the basics of Auth:

Create a new user (e.g. if you have not set up any users yet and want to do that programmatically)

$model = ORM::factory('user');
$model->values(array(
   'username' => 'admin',
   'email' => 'admin@example.com',
   'password' => 'admin',
   'password_confirm' => 'admin',
));
$model->save();
// remember to add the login role AND the admin role
// add a role; add() executes the query immediately
$model->add('roles', ORM::factory('role')->where('name', '=', 'login')->find());
$model->add('roles', ORM::factory('role')->where('name', '=', 'admin')->find());

Check whether current user has a role

Auth::instance()->logged_in('admin') // for current user

Check whether some other user has a role

// Load the role
$role = ORM::factory('role', array('name' => 'admin));
// Check that the user has the given role
$status = $user->has('roles', $role);

Add a role to a user

// add() executes the query immediately, and saves the data (unlike the KO2 docs say)
$user->add('roles', ORM::factory('role')->where('name', '=', 'admin')->find());

Remove a role from a user

// remove() executes the query immediately
$user->remove('roles', ORM::factory('role')->where('name', '=', 'admin')->find());

Retrieve all users that have a particular role

// find all the reviewer users in order of their username
$role = ORM::factory('role')->where('name', '=', 'reviewer')->find();
$users = $role->users->order_by('username', 'DESC')->find_all();
foreach($users as $user) {...}

Documentation on the interesting bits

The template view

The template view in /views/default/template.php uses the Thematic-inspired markup which I discuss in this post. You can do a lot by adding a few more divs into the header div. I have tried to follow my own advice about CSS, but the included CSS file is pretty basic. It includes the Yahoo CSS reset.

Controller_App: base controller class

This is the “base” controller I use for all the classes. It handles template autoloading and auth checks. You should inherit all your controllers from Controller_App to benefit from its features.

There is also one additional neat thing: in case of session expiry, Kohana may show an error in session loading. There is an additional check for this in Controller_App, which discards the session in case of loading errors.

Template autoloading loads the file from /views/default/template.php, so that you just have to set $this->template->content = $view->render() in your controller.

Auth checks are configured through two additional properties in the controller:

/**
 * Controls access for the whole controller, if not set to
FALSE we will only allow user roles specified.
 *
 * See Controller_App for how this implemented.
 *
 * Can be set to a string or an array, for example array('login', 'admin') or 'login'
 */
public $auth_required = FALSE;

/** Controls access for separate actions
 *
 *  See Controller_App for how this implemented.
 *
 *  Examples:
 * 'adminpanel' => 'admin' will only allow users with
the role admin to access action_adminpanel
 * 'moderatorpanel' => array('login', 'moderator') will
only allow users with the roles login and moderator to access action_moderatorpanel
 */
public $secure_actions = array();

Controller_User: Controller for user self-management

Particularly interesting code is in the register view, which shows how you can load validation error messages from a file, and how you might alter classes to show errors.

You might want to improve that code, I haven’t had the time to create a proper helper for this.

  • action_index shows how to check for a particular role using auth
  • action_noaccess is the generic “access denied” view.
  • action_profile and action_profile_edit show how to load data, and how to validate data on save. See application/modules/user.php for details on how the validation is done.
  • action_register shows how to create a new user.
  • action_unregister shows how to delete the current user, and log them off programmatically.
  • action_forgot is a basic example of how forgotten passwords might be recovered. I haven’t implemented the email sending functionality for now, so if you do it, please contribute here.
  • action_reset resets the user password if the user knows the 32-letter recovery key which should be emailed to them.

Controller_Admin_User: Controller for administering users

You need the admin and login privileges to access this controller.

There is a sample implementation of how to use Kohana 3 pagination in the index view. This could be improved e.g. by a helper that would take into account the sort state.

  • action_index is a sample of how pagination can be used.
  • action_edit is the administrative edit and add for new users. It shows how to add roles to users and also how to combine editing and adding new users into one action
  • action_delete is the administrative delete function for deleting users.

Model_User: Model for users

This code is mostly based on Model_Auth_User (in /modules/auth/classes/model/auth/user.php). However, I extended the login() function to support failing after too many attempts over a 5-minute period.

The “too many recent failed logins” functionality is commented out, since it will need a few additional fields.

Also, you might want to add the “created” and “modified” columns, there is a comment showing how this can be done using ORM functionality.

Questions, comments, thanks, contributions?

Leave a comment below… or ask on the Kohana forums.


52 comments


  1. Wow…thanks so much. I have an application that’s I’m using that I didn’t write and the user management was missing and it in process of dinking around with the database I kinda messed thing up a bit.

    Long story short(er) I found your article here and added domain management pretty easily by just installing your whole sample then hooking to the other database and with a few tweeks here and there I created a user management app for my application.

    Thanks so much…great work.

    P.S. Kohana drives me nuts.

  2. When I check out the source code, I cannot find the files related to this tutorial, only a welcome.php in the controller folder. Am I missing something here?

    • The auth implementation is a module, so the files are in the modules/user/ directory, not under app/.

      This is useful because if you already have an app, you can just copy the modules/user/ folder and enable it in bootstrap.php (before loading the core Auth module). Also, you can extend the module using the Kohana 3 HMVC mechanism by redefining e.g. the user model in app/models/.

  3. Mikito, thanks so much for this module! One issue that I’m initially running into: when I go to edit a user to say, change the role,, I get this error:

    “Invalid method validate_edit called in Model_User”

    (this is the call from line 88 in Controller_Admin_User)

    But this very method– validate_edit() — is right there in Model_User. I’m still trying to figure out why I’m getting this error.

  4. Robert Van Sant

    Thanks so much for this explanation and code sample. Sometimes I feel Kohana is great and sometimes I feel like why isn’t it easier like CodeIgniter. I definitely like that it’s strict PHP5 coding, hence why I’m trying very hard to learn the nuances of the Kohana framework. I have a question in terms of templating and Ajax. What is the best route to handle this. Is it a matter of returning the rendered blocks as a response and using a replace JavaScript function to replace that HTML block? I’ve done this before with other projects.

    Thanks in advance for any advice.

    • I’ve looked into some of the possabilities myself and I have decided that the best is to use json_encode(array(–vars here–)); For another project I simply wrote a simple array to xml class instead.

      If you are using a template controller you will need to do something there not to get the header and footer.

      • Here’s the way I worked out for apps with heavy Ajax usage. Rather than having to duplicate a lot of actions I set my main controller to detect if it was an Ajax request. If it was set the template to an json encoded output.

        In my actions I prepare all values into the same variables for each $values, $errors, $messages etc.

        The Json view combines $values, $errors and $messages into a single array and runs it through json_encode and prints it.

        Doing it this way you have less code to write and it’s easier to maintain when you have to make changes.

  5. Thanks for this great tutorial! I’m new with user-management, but I see in another user-manager a “Session Manager” with a session database table, here I not understand to handling the sessions. Is this session-table not necessary?

    In this time there is no data for “user is online” or “user is offline since ???” or a list of online users. Coming this in a next tutorial? :)

    • If you want to implement this, there are basically two additional things you need to do:

      1: keep track of when the user was last active (e.g. on each page load, update a value somewhere in the database)

      2: show users as online if they were active within the last x minutes (e.g. a page load occurred in the last 15 minutes)

      Sessions do no need any tables, they are a core functionality of PHP, see http://www.php.net/manual/en/function.session-start.php and are not stored in the database.

      You can keep track of sessions in a table if you want to show other people whether a user is online. However, my focus here is on Auth and user account management, so the I only keep track of the last login (you can see that in the admin interface).

      If you want to track user activity, you need to write the additional tracking yourself.

  6. hey mikito,

    thanks for this realy nice backend and tutorial.
    it runs verry well with my kohana 3.0.8 except the
    $user->reset_token function is missing. is this a known bug, or is this a configuration problem from myself?
    i will add an additional functionality for validating an email adress by the user after registration, when i have time again.

  7. Am I missing something? I downloaded the source, but the ‘application/classes/controller’ folder is empty aside from a default welcome.php file. Where are all the controller class files?

  8. Hi,
    I read your tutorial, which I mainly understand( I think ), but there is one thing that I dont understand, (i am new to Kohana), I thought that you needed to load your module in bootsrap, but I have searched, and havent seen where you did it…

    I want to develop a module myself so i was wondering…

  9. Oh my god! THANK YOU, I am getting into Kohana and well the most buggery thing is the auth and user controls with roles :D so you have just saved me a arm and a leg and allow me to get knowing kohana from the heart of what i require todo :D

    10/10

  10. Hello Mikito!
    I learned your class Model_Useradmin_User and there’s area that i can’t understand.
    In method login() you call:
    if ($this->loaded() AND Auth::instance()->login($this, $array['password'])) {….
    but
    Auth::login(…){

    $this->_login($username, $password, $remember);

    }
    and _login is abstract method which have to be defined for user.
    I tried to find subclass Auth where this and other two abstract method have to be defined but i couldn’t find it. Please help my investigate it.

    • Hi Anton,

      I am using the KO3 core Auth class. And as you can see in /modules/auth/classes /kohana/auth.php function instance(), the actual class is determined by configuration.

      Auth can be configured at application/config/auth.php to either use the ORM driver or file driver. The default, and the one I test with is the ORM driver.

      The concrete code for login() that is located in /modules/auth/classes/ kohana/auth/orm.php . Note that this is all KO3 core code.

  11. I have some question about your model. Why did y not write logged_in method and other like Kohana_Auth? Or do y think it’s bad idea and need use Auth::logged_in method in controllers?

    • Is it good idea write wrapper Kohana_Auth_Orm::logged_in() method?

      • Hi,

        not sure I understand your question. I’m not writing any wrappers for Auth, because I am not trying to replace the core Auth functionality – I just want to build a module that uses KO3 Core Auth and adds the most commonly used functionality. So I only use/inherit from Auth, and extend the base Auth_User model a little bit in my User model to provide password resets and validation for changing the password after registering.

        Why should there be a wrapper for Auth::logged_in? What would be the benefit?

  12. Hey, nice job you did there, Mikito! Are you going to update the module to work with the newest kohana version (3.1.1)? It would be great!

    • I am going to release a rather big and awesome update soon with Twitter, Google and Yahoo support as well as a new UI, it’ll be out very soon (a couple of days?).

      I will update to 3.1.x at some point, but not immediately as I am swamped with other work and the 3.0.x branch is still working perfectly fine (and is still supported).
      Looking at http://forum.kohanaframework.org/discussion/7793/kohana-3.0-to-3.1-upgrade-troubleshooting there are quite a few things to test/debug etc. The main issue is that KO 3.0.x Auth hashes aren’t supported on 3.1.x and I don’t have the time to figure out the migration right now.

      Please give it a try yourself if you need to have KO 3.1.x support quickly.

  13. Can’t wait :) Hope you get it done quick.

  14. Hi,
    Finally I can make your module works for Ko3.1.
    I’m not a good coder, and my kohana exprience is minimal, so I don’t know whether my modification is the proper one.

    The modification is 1-4 lines per function, except for action_profile_edit, I made a lot of changes.

    not sure where to put my code, just ask me I’ll email to who interested.

  15. Mikito, thanks for building and sharing such a great module!

    At first I ran into an issue because the driver (stupid me) was set to “File” and needed to be set to “ORM”. That was easy to fix.

    Then, it expected the pagination module, which was also pretty easy to add.

    Now I’m getting an error saying that “The user_identity property does not exist in the Model_User class”. It looks like that’s related to the outside user identities (Facebook, Google, etc.). Is there a swing table it’s looking for or something? Anything else I need to do to set that up?

    Thanks in advance for the help!

    • Great!

      You are probably loading the modules in the wrong order – so the Auth module Model_User is being used instead of the Useradmin module Model_User. The Auth version of Model_User does not have the additional relationships. Recheck your module loading order in bootstrap.php. More info in the “Getting Started with Useradmin” post: http://blog.mixu.net/2011/01/13/getting-started-with-useradmin-my-kohana-3-auth-admin-module/

      Also, make sure you have the database structure from the SQL file in the module directory (foreign key constraints are not important if it complains about those).

      Reading about your troubles reminds me that I should offer a “ready to go” version as well. There used to be one, but heavy Git/Github users prefer pure modules over full applications…

      • Hi, I’m having the same problem as Joe Dwyer, but my bootstrap is fine I think.

        The user_identity property does not exist in the Model_User class

        The problem is when I use pagination (admin_user).

        Kohana::modules(array(
        ‘useradmin’ => MODPATH . ‘useradmin’, // Mixu’s useradmin module
        ‘auth’ => MODPATH . ‘auth’, // Basic authentication
        multiple backends
        ‘database’ => MODPATH . ‘database’, // Database access
        ‘orm’ => MODPATH . ‘orm’, // Object Relationship Mapping
        ‘pagination’ => MODPATH . ‘pagination’, // pagination
        ));

        “Ready to go” would be awesome!

  16. Mikito! You are awesome! Thanks for the quick response. Looks like it’s working now.

    I understand users wanting pure modules, but I agree it’s nice to have a fully “ready to go” version for people who are learning Kohana. It’s much easier to throw something up, see that it works, and then start tweaking. When the tweaks break something… it’s pretty easy to figure out what happened. But when you can’t get it to work in the first place, it’s much harder to figure out where the error is. After I get more used to Kohana, I suspect that won’t be as much of an issue, though…

    Have a great weekend!

  17. You have my undying love and gratitude. This is awesome!!! Exactly what was needed at exactly the right time. Thank-you very much for a GREAT job, stunningly executed. I had a few minor issues… not sure if they are typical or not… like user.last_failed_login and user.modified needing default values…. but this was as painless as it comes… and it does EXACTLY what it said on the box. Thanks again. Many karmic hugs.

  18. I have done everything described above but I am getting 404 error when I want to see x/user/login. ‘x’ is my base url. I cant understand why my default route does not catch the uri. I have declared the user module before the auth module.
    My default route is:

    Route::set(‘x/user’, ‘user(/(/))’)
    ->defaults(array(
    ‘controller’ => ‘user’,
    ‘action’ => ‘index’,
    ‘id’ => NULL,
    ));
    Route::set(‘default’, ‘((/(/)))’)
    ->defaults(array(
    ‘controller’ => ‘main’,
    ‘action’ => ‘index’,
    ));

  19. Great Job, using it for my project and loving it :D
    There is jeust a little challenge regarding the auto_login part with a cookie, as you say the kohana auth module handle it very well but there is a little problem with your database. The token field in the user_tokens table should be a varchar(40) and not 32.
    It now works better for me ^^
    Thank you very much once again, keep up enhancing the stuff, I’m planning to fork it sometime ;)

  20. Hi I’m trying to find the folder /modules/user in the github repository as mentioned in the post but I cannot seem to see this folder.

    Can anyone give me any pointers where this module is?

    Thanks in advance

  21. Hi, I am a newbie to Kohana, and was trying to setup this as my starting point. I’ve downloaded the code from github, but wasn’t successful in getting this running in my local. Is there any documentation about how to set this up? Or would you be able to give me the steps required for setting the code?
    Thanks A LOT in advance!

  22. @Guidouil, thank you so much for your comment.

  23. Hi, i was wondering if its possible to use the Auth Module without the use of roles ? or am i bound to use them, unless i want to rewrite the module or make my own ?

    Kind regards, iPoul

Leave a comment

You must be logged in to post a comment.