Auth library for CodeIgniter tutorial.

Hello and welcome to my first tutorial in ages. Today, I’ll be explaining to you how you can create a simple login (or ‘auth’, short for authorization) library for CodeIgniter.

What functionality will our library have? Users accessing restricted pages will see a login screen if they’re not logged in, once logged in they’ll be redirected to the page where they were, or simply see a standard page. That’s about it for this tutorial, though adding things like user groups, restrictions etc… could all be added later. Maybe stuff for a later tutorial?

I’ll copy/paste bits of code from my own (simple) auth library and then explain what they do. So at the end of this tutorial you will have a working library.

For starters, let’s quickly rethink how we used to do this kind of stuff with procedural PHP. What I used to do was set a $_SESSION variable, most of the time $_SESSION[‘loggedin’] = true; or something like that. If it was false, or not set, I would check if cookies were set with the username and/or hashed password. Or I would check if the submit form was submitted. I would process that data and see if a valid user entered his/her name and password. It was then but a case to create an index page that checked for that session variable to display the login form or the actual content. Probably not the safest way, but it worked like a charm.

With CodeIgniter and the MVC approach, things aren’t that different. But, they can be a little confusing at first. I know they were for me, that’s why I’m writing this tutorial.
Before we start, let me just say I’m presuming some things:
- You have some knowledge of PHP and you grasp some basic Object Oriented PHP lingo, so you won’t have to ask “Excuse me, but what does ‘construct’ mean?”.
- Comes with the previous one: you at least know what CodeIgniter is. If you don’t know what CI is, I suggest you first go read the user guide, which is excellent by the way.
- You use a mysql database to store your users and their passwords. If you haven’t got a user table yet, but you’re planning on using one, here’s some SQL to help you create a table. It also adds a standard user, named User with the password Applepie.

CREATE TABLE `users` (
  `id` int(11) NOT NULL auto_increment,
  `username` varchar(255) NOT NULL,
  `password` varchar(255) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;

INSERT INTO `users` SET `username` = 'User', `password` = 'Applepie';

Okay, your still here. Your users need to login to see certain pages, so you’ll offcourse need a controller.

<?php
class Admin extends Controller {

	function Admin()
	{
		parent::Controller();
	}

	function index()
	{
		// Show some fancy stuff, like a dashboard
		// OR, just use index as a placeholder for another, 'standard', method, like so:
		$this->news();
	}

	function news()
	{
		// Post some news items
	}

}
?>

We could add some lines code to all of our methods that check for a session variable (because that’s what we’ll use here too), and then decide to display the actual page or a login view. But we’d have to repeat it in every method and if we’d have to change it, we’d have to change it in every method. That’s not very DRY, is it?

You know what we’ll do? Let’s create an additional method, which sole function will be displaying and processing the login form. If we’re not logged in, we can redirect to it. So let’s add our login method.

<?php
class Admin extends Controller {

	function Admin()
	{
		parent::Controller();

	}

	function index()
	{
		// Show some fancy stuff, like a dashboard
		// OR, just use index as a placeholder for another, 'standard', method, like so:
		$this->news();
	}

	function news()
	{
		// Post some news items
	}

	function login()
	{
		$this->load->view('login');
	}
}
?>

and our view file could look like this:

<h2>Please log in first</h2>
<form action="/index.php/admin/login" method="post">
<!-- as you can see, the action refers to the same page -->
<p>
	<label for="username">Username: <br />
	<input type="text" name="username" value="" id="username"  /></label>
</p>
<p>
	<label for="password">Password: <br />
	<input type="password" name="password" value="" id="password"  /></label>
</p>
<p>
	<input type="submit" name="submLogin" value="Log In"  />
</p>
</form>

For the sake of shortness, I won’t include validation for this form, this is easy enough to figure out yourself.

So far for displaying the form, on to the next bit: processing it!

Again, for the sake of shortness, I’m not including any cookies either. If you want to store the username and password in cookies, this is easy enough to do yourself.

Let’s rewrite our login method so it can process the data from the login.

function login()
{
	if ($this->input->post('submLogin') != FALSE)
	{
		$login = array($this->input->post('username'), $this->input->post('password'));
		if($this->auth->process_login($login))
		{
			// Login successful, let's redirect.
			$this->auth->redirect();
		}
		else
		{
			$data['error'] = 'Login failed, please try again';
			$this->load->vars($data);
		}
	}
	$this->load->view('login');
}

Whoa, whoa. $this->auth? I skipped a step, don’t worry. If you would submit your form now, you’d get a pretty error saying it can’t find the process_login method or the auth library. That’s because ‘auth’ is the library we’re going to create. CI can’t know what’s not there yet. We’ll do that in a second. First, let’s change a few things:
Start with changing your login view so it looks like this.

<h2>Please log in first</h2>
<?php
if(isset($error))
{
	echo "<p>$error</p>";
}
?>
<form action="/CI/index.php/admin/login" method="post">
<!-- as you can see, the action refers to the same page -->
<p>
	<label for="username">Username: <br />
	<input type="text" name="username" value="" id="username"  /></label>
</p>
<p>
	<label for="passw">Password: <br />
	<input type="password" name="password" value="" id="passw"  /></label>
</p>
<p>
	<input type="submit" name="submLogin" value="Log In"  />
</p>
</form>

Now your users will see the error message if they enter a wrong username or password.

Also, let’s add the following line to your controller construct:

$this->load->library('auth');

It’ll throw an error for now because the library isn’t created yet, but we’ll do that on the next page.

Bookmark:
  • Digg
  • del.icio.us
  • StumbleUpon
  • Technorati
  • Reddit
  • TwitThis
  • Facebook
  • E-mail this story to a friend!

Pages: 1 2 3 4

39 people left their say »

  • [...] contact Bramme.net « Auth library for CodeIgniter tutorial. [...]

  • It’ll throw an error for now because the library isn’t created yet, but we’ll do that on the next page.

    Where is the ‘next page’?

  • My bad, there’s no next page link. I’ll fix it as soon as possible! I’m at work right now and don’t have access to my editor.

  • Thanks for the generous walkthrough and code. It was very beneficial to me and practically the last piece of the puzzle to a couple of projects. :)

  • It works like a charm, thank you very, very much..

  • A couple of security related notes:

    1) Sticking the username and password in a cookie is a bad idea, I know you did not suggest it but you mentioned it and it is a major ‘no-no’. Use builtin session storage or create your own session id and send it in a cookie but please don’t put the username and password in the cookie.

    2) Hashing the password is a must for security, I am glad you mentioned it. It also protects against SQL Injection robbing users passwords (SELECT username, password from users). I would highly recommend it.

    Thanks for the tutorial, I am moving a site to CI and this gives me some insight into how others are creating auth within CI.

  • Thank you very much for the tutorial. It was a great help in developing a site I’m working on.
    Although I would like to see other features implemented like user groups, restrictions, etc… Are you planing to write this tuts…?

    Once again, thank you!

  • excellent tutorial. thank you very much…

    i did run into an issue however with the syntax of naming the constructor ‘__construct’ rather than the name of the class ‘Auth’. though you have it done correctly in the tutorial, the files you have for download still have ‘__construct’.

    thanks again!

  • techdubb: That is a conflict between PHP4 and 5, the “__construct” syntax is explicitly version 5, so I expect you have 4 running on your end?

  • Good site I “Stumbledupon” it today and gave it a stumble for you.. looking forward to seeing what else you have..later

  • keep it up man! great work!

  • Any idea what could be causing me to get the error “cannot redeclare class Auth on line 3 of Auth.php” ? I haven’t altered your files at all. Thanks

  • any chance you’re loading the library twice? like autoloading it and then also loading in your controller?

    Could also happen if you have a model or other library called auth

  • Fatal error: Call to a member function on a non-object in c:\web\arsite\cms\system\application\libraries\Auth.php on line 114

    this is the error that am getting when I go index.php/admin/

  • can you help me for the error

  • I suggest you post more code over at the CodeIgniter forums. With just the error message I’m nothing.

  • It works like a charm, thank you!

    Although, i was wondering if it is possible to add something like:

    If (logged_in) {
    echo “logout link”
    }

    in the view file, so that i can check if the user is logged in and display links that only a logged in user i supposed to see…

    Thanks again!

  • Cannot modify header information - headers already sent
    Filename: libraries/Session.php
    error occuring while using session ,
    pls clarify

    • This is problem has nothing to do with the Auth lib. It is caused by output before you set sessions. Commonly, this can be caused by echo’ing variables from your controller, whitespace or linebreaks before your starting

      I suggest you check all your controllers/models/libraries/helpers for any output (or whitespace). If the problem persists, it might be a good idea to write a post on the CodeIgniter forums.

  • thank u for reply, it caused because of whitespaces,i hav cleared it

  • $this->CI->session->userdata(’redirected_from’), what we have to specify instead of redirect_from in the function redirect,did we have to define the location in the session.php in the library or is it is an inbuilt one in codeIgniter.
    pls reply

  • You do not have to replace it, nor is it inbuilt by CodeIgniter: it’s taken care of by the Auth library: you’ll see the variable ‘redirected_from’ being set in the “restrict” function.

  • is it suppose to be like this?

    if(!isset($login))
    {
    return FALSE;
    }

    if(count($login) != 2)
    {
    return FALSE;
    }
    else
    {
    $username = $login[0];
    $password = $login[1];
    }

  • Thanks for the tutorial. Everything worked perfectly.

  • this is exactly what i’ve been looking for - many thanks!!!

    something lightweight enough for me to get going, without all of the bloat of freak, redux, or auth…

    txs

  • Thank you for the tutorial working fine but with FF, Safari and Chrome are working fine but not with IE(v.7) (I didn’t check with IE6)

    How can I fix it?

    • CodeIgniter works on the serverside, not client side. Which browser you’re using shouldn’t affect the system. Unless IE7 is bugging out on something in the session library. What version of CI are you using?

      • I’m using latest version of CI 1.7.1.

        Is this issue something to do with godday server? I had a difficult time setting CI with their server.

        It seems like something wrong with session. After logout, I can still access to portfolio page(news page works as expected). Also after login, I can still go back login page. This issue is only reproducible with IE7

        • Hmmm, I’m not sure. I’ve heard problems before with godaddy concerning .htaccess files. You might wanna ask around on the CI forums. Maybe somebody could help there.

          Also note: the session library has changed since I wrote this tutorial. I’ve been meaning to update it or write a new one, but I just didn’t get to it yet.

          • lc said
            on Mar 24th, 10:10 pm |

            After checked CI forums, I found out that many people has IE7 session issue but none of comment solve my issue :(

            However, I change 2 lines of Auth.php and now working as expected
            (tested: IE6, IE7, FF, Chrome, safari)

            Auth.php
            ==================================================
            /**
            *
            * This function redirects users after logging in
            *
            * @access public
            * @return void
            */
            function redirect() {
            if ($this->CI->session->userdata(’redirectedFrom’) == “”){
            //if ($this->CI->session->userdata(’redirectedFrom’) == FALSE){

            ==================================================

            Auth.php
            ==================================================
            /**
            *
            * Checks if a user is logged in
            *
            * @access public
            * @return boolean
            */
            function logged_in(){
            if ($this->CI->session->userdata(’loggedUser’) == “”){
            //if ($this->CI->session->userdata(’loggedUser’) == FALSE){
            return FALSE;

            ==================================================

  • You saved me loads of time… thanks a lot!

  • Bram! Thank you so much for writing this tutorial! This is exactly what I need! I need to learn how to work out authentication in CI but I really avoided using auth frameworks because most of the times they’re really overwhelming and I really like writing code myself so I can better understand CI.

    I already implemented your tutorial and I’m happy that it works! Keep up the good work and looking forward to your CI articles. Btw your English if fine!

    Thank you Bram!

    Tip: Try body { line-height:1.5em; } for better readability.

  • A Database Error Occurred
    Error Number: 1364

    Field ‘user_data’ doesn’t have a default value

    INSERT INTO `ci_sessions` (`session_id`, `ip_address`, `user_agent`, `last_activity`) VALUES (’17f14ae9124b9730ed16186540dd220e’, ‘192.168.0.50′, ‘Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;’, 1239254885)

    please clarify this error

    • Dunno where it comes from… Is it possible that you’re using CI 1.7.x ? This tutorial was written for CI 1.6.x, with 1.7 the CI session library changed and things might not be compatible anymore.

  • Wow, thats exactly what i was searching for! Thank you!

  • A PHP Error was encountered

    Severity: Notice

    Message: fwrite() [function.fwrite]: send of 38 bytes failed with errno=32 Broken pipe

    Filename: libraries/Email.php

    Line Number: 1707
    this error occured whhen i tried to mail some contents. can u pls clarify why its happening

Have your say »