A Sample CodeIgniter Application with Login And Session

Code Igniter App Screenshot

CODE | DEMO

UPDATE: This is the third of a three part series on CodeIgniter, Redis, and Socket.IO integration. Please be sure to read the other posts as well.
Part 1: You are here.
Part 2: Use Redis instead of MySQL for CodeIgniter Session Data
Part 3: Live Updates in CodeIgniter with Socket.IO and Redis

I was assigned to work on a PHP project a few weeks back that utilized the CodeIgniter framework. I’ve used MVC frameworks in the past in other languages, and because CodeIgniter does not deviate too far from common MVC patterns, it was pretty easy to pick up. To get myself up to speed, I put together a sample project based of what I learned from the documentation and a few tutorials. It’s a small microblogging app with very basic user auth and CRUD functionality. The basics of it go like this…

  • User login screen with basic password authentication.
  • Each user is assigned a ‘team’ number. Users can only view posts from their teammates.
  • An admin can view all posts from all users.
  • Each user has a ‘tagline’.
  • The tagline can be edited by clicking on it and typing something new (modern browsers only, as it uses ‘contenteditable’)
  • Hovering over a user’s avatar reveals the username and tagline for that user.
  • Admins can create new user accounts.
  • A user’s own messages appear below their profile. This is limited by 5 posts, currently.
  • Careful, there is not much form validation going on at the moment.

Building it gave me a good feel for the basic mechanics of CodeIgniter and allowed me to brush up on some PHP. The real motivation behind this project, however, is to eventually work in a Socket.IO implementation to allow real time updates for the user. I’ve been eyeing NodeJS for quite some time now, but never really had cause to use it. Fortunately, the project I was working on needed a more robust and scalable ‘real time’ framework to replace a rudimentary long-polling system. Socket.IO would have been a pretty good solution, in my opinion. Unfortunately, the project was cancelled before I could get started. But since I’ve already got the ball rolling on this sample application, I figure I might as well finish, and learn a few things in case a situation like this arises again. You never know…

The Setup

The front end of the application uses Twitter Bootstrap for styling and layout, jQuery for client-side interactivity, PHP and CodeIgniter for most of the functionality, and MySQL for data storage. This is a fairly common toolset that runs on most L/W/M/AMP-style environment stacks. The code available on GitHub has everything you need to run the app yourself, provided you have a web server, MySQL, and PHP 5.3 or greater.

You’ll need to create a database (preferably called ‘cisock’), and then import cisock.sql in the root of the ‘partOne’ folder in the repository. You can do this with the following command from the command line (be sure to change ‘yourusername’ and ‘/path/to/’ to match your local setup):

mysql -u yourusername -p -h localhost cisock < /path/to/cisock.sql

Once you’ve gotten the code checked out into your web root and the SQL imported, you’ll need to do some slight configuration before getting started. In ‘part_one/application/config/config.php’ you will need to change line 17 to reflect your local URL. If you simply cloned the project directly into your ‘localhost’ web root, then no changes will likely be needed. A similar fix is necessary in ‘part_one/assets/js/main.js’ line 6. The context root of your application goes here. Again, if you cloned to your web root, the default value should be fine. Ideally, the context root should only have to be configured in one place, but it is what it is for now.

Secondly, the settings in ‘part_one/application/config/database.php’ must be set to reflect your local database configuration. The following entries are specific to your local environment:

$db['default']['hostname'] = 'localhost';
$db['default']['username'] = 'yourdatabaseusernamehere';
$db['default']['password'] = 'yourdatabasepasswordhere';
$db['default']['database'] = 'cisock'; //or use the database name you chose, if it is different

Once that is done, you should be able to navigate your browser to the /part_one/ directory and see the login screen.

To recap:
  1. Clone the repo
  2. Set up the database and import the tables from cisock.sql
  3. Edit database.php and also config.php and main.js if necessary

The Code

I tried to follow suggested CodeIgniter conventions as closely as possible. As such, the file and directory structure is pretty much as it is out of the box. I altered /application/config/routes.php to set the login controller as the entry point for the application like so:

$route['default_controller'] = "login";

The index method in /application/controllers/login.php checks to see if the user is logged in, and if not will redirect to the login screen by calling the show_login function. The code immediately below is login/index – which will run when application’s url is loaded in the browser.

function index() {
    if( $this->session->userdata('isLoggedIn') ) {
        redirect('/main/show_main');
    } else {
        $this->show_login(false);
    }
}

Because the ‘isLoggedIn’ session variable starts out as false, the show_login() function is called. The ‘false’ argument indicates that an error message is not to be shown.

function show_login( $show_error = false ) {
    $data['error'] = $show_error;

    $this->load->helper('form');
    $this->load->view('login',$data);
}

That last line there: $this->load->view('login',$data); is what opens up the login view ( /application/views/login.php ). When the user types in credentials and clicks the ‘sign-in’ button, the login_user function is called through a normal form POST as indicated by this line of code in /application/views/login.php: echo form_open('login/login_user') ?>. The form_open function is part of CodeIgniter’s Form Helper, which generates the form’s HTML for you.

The login/login_user function gives us our first taste of a CodeIgniter model. It loads up an instance of a user model and calls the validate_user method on that model, passing it the email and password typed in by the user. Take a look at the code below for the entire sequence.

  function login_user() {
      // Create an instance of the user model
      $this->load->model('user_m');

      // Grab the email and password from the form POST
      $email = $this->input->post('email');
      $pass  = $this->input->post('password');

      //Ensure values exist for email and pass, and validate the user's credentials
      if( $email && $pass && $this->user_m->validate_user($email,$pass)) {
          // If the user is valid, redirect to the main view
          redirect('/main/show_main');
      } else {
          // Otherwise show the login screen with an error message.
          $this->show_login(true);
      }
  }

In the ‘user’ model, a couple of interesting things happen. First, a query is built using CodeIgniter’s ActiveRecord implementation. The username and password entered by the user are compared to the user table in the database to see if the credentials exist. If so, the corresponding record in the database will be retrieved. If that happens, the data retrieved from the database will be used to set session variables using the set_session function of CodeIgniter’s Session class. All the code for this is in /application/model/user_m.php and can be seen below.

var $details;

function validate_user( $email, $password ) {
    // Build a query to retrieve the user's details
    // based on the received username and password
    $this->db->from('user');
    $this->db->where('email',$email );
    $this->db->where( 'password', sha1($password) );
    $login = $this->db->get()->result();

    // The results of the query are stored in $login.
    // If a value exists, then the user account exists and is validated
    if ( is_array($login) && count($login) == 1 ) {
        // Set the users details into the $details property of this class
        $this->details = $login[0];
        // Call set_session to set the user's session vars via CodeIgniter
        $this->set_session();
        return true;
    }

    return false;
}

function set_session() {
    // session->set_userdata is a CodeIgniter function that
    // stores data in a cookie in the user's browser.  Some of the values are built in
    // to CodeIgniter, others are added (like the IP address).  See CodeIgniter's documentation for details.
    $this->session->set_userdata( array(
            'id'=>$this->details->id,
            'name'=> $this->details->firstName . ' ' . $this->details->lastName,
            'email'=>$this->details->email,
            'avatar'=>$this->details->avatar,
            'tagline'=>$this->details->tagline,
            'isAdmin'=>$this->details->isAdmin,
            'teamId'=>$this->details->teamId,
            'isLoggedIn'=>true
        )
    );
}

So now that the user is authenticated and their session info is set in a cookie, CodeIgniter will take an extra step and store the user’s IP address, session ID, user agent string and last activity timestamp in the database. So when the user logs out, closes the browser, or is idle for too long, the session will expire and be cleared from the database. If someone with a cookie containing the same session ID then tries to connect to the application, it will be invalid because it won’t match any of the sessions stored in the database. Check out the Session class documentation for a more thorough explanation.

So now that the user is logged in, the ‘main’ controller can do its thing. The show_main function runs just before loading the main view, and does a number of things to prepare for displaying the view to the user. The user’s details are used to change certain parts of the view, such as which posts to display (team only, or everyone) and the admin controls.

The show_main function grabs some data from the user’s session, retrieves all the user’s posted messages, counts the total number of messages posted by the user, and retrieves the messages from other users. All of this info is placed into the $data object and passed to the ‘main’ view (/application/views/main.php). Much of the heavy lifting is taken care of by ActiveRecord commands in the Post model (/application/model/post_m).

That’s about it, as far as logging in goes. Now that everything is set up using conventional CodeIgniter practices, I can begin the process of converting the server side session data to be stored in Redis, rather than in a MySQL table…

UPDATE:
See Part 2: Use Redis instead of MySQL for CodeIgniter Session Data
and Part 3: Live Updates in CodeIgniter with Socket.IO and Redis

50 Comments

  1. Hi, what is the user and password for the DEMO?

  2. Whoops, sorry. I thought I posted this on the login screen but it looks like I forgot to update it.

    Admin user email:
    Team 1 user email:
    Team 2 user email:
    The password for each user is ‘password’
    The database is reset every night.

  3. Thank you. I had an issue. When i installed it in my local system, the login page is coming, but after entering the logins, its not taking me to the ..index.php/main/show_main/

  4. sorry, thanks. i figured it out. :)

  5. after clicking on “Post New Message” button, it is not reflecting on team members view quickly. We need to refresh the page. So what should we do to see the quick reply?

  6. Great code, but I get the following error :
    Fatal error: Class ‘Redis’ not found in C:\Program Files\EasyPHP-5.3.8.1\www\test8\application\libraries\MY_Session.php on line 33

    Do you know what I’ve to do to install the Redis at the EasyPHP ?

  7. @majit, the version of the application in part 1 will not auto-update. Only part 3, with Redis and NodeJS properly installed will auto update without refreshing. Please see the following articles in this series:
    https://ericterpstra.com/2013/03/use-redis-instead-of-mysql-for-codeigniter-session-data/
    https://ericterpstra.com/2013/04/live-updates-in-codeigniter-with-socket-io-and-redis/

    @Joseph, You must first install teh Redis class on your system. Follow the instructions on this page to get started: https://github.com/nicolasff/phpredis

  8. Interesting post. pls how can i send invalid username or password message back to the login page?

  9. i can not use fill_session_data method of user_model ..when i use this method and pass the data to view ,,,always error message like this:::
    “A PHP Error was encountered
    Severity: Notice
    Message: Undefined variable: data
    Filename: controllers/index.php”;

    my code like this::::
    controller:::
    public function index()
    {

    $data = $this->user_model->fill_session_data($data);

    $this -> load -> view(‘view_index’, $data);

  10. very good example of Code igniter session login.

  11. Interesting code and app thanks for sharing

  12. Hi,
    session is not working properly
    Login is working good but after logout if you go back it shows your last runing session
    can you please give me solution of this?
    please reply me ASAP

  13. Can you please reply me?

  14. Hi, I am traveling right now and not able to look into this too deeply. If you check the official CodeIgniter documentation, I think there is an option in config.php to clear the session when the browser is closed. Otherwise the expired sessions in the database are randomly cleared via garbage collection.

  15. Hi,

    Thank You for your reply.

    I have already do all this thing.but still this problem occurred.
    After log out the page is redirect to where I want but the main problem is with the session, session is not destroyed after log out and if you click on the back button it will return to the last page and shows the last running session.
    Please help me to solve this problem.

  16. Yeah, I see what you mean. Unfortunately I don’t have time to add code to fix it right now. The example in this post is really just to build up to the SocketIO + Redis example in part 3, and it is not intended to be a production ready solution for login and session. If you want some more robust code for CodeIgniter login, take a look at some of these libraries:

    Auth Me: https://github.com/gilbitron/CodeIgniter-Authme
    Flexi Auth: http://haseydesign.com/flexi-auth/
    ION Auth: https://github.com/benedmunds/CodeIgniter-Ion-Auth

  17. Hello,

    First of all sorry for disturb you again and again.
    I have checked all the links you have mention in your post.But still the problem is not solved. Please help me to solve my problem.

  18. Hi,
    your code is fine, but when i logout and then press back button(go back page), it is still showing the “http://apps.ericterpstra.com/ci_sock/part_one/index.php/main/show_main” page rather then “http://apps.ericterpstra.com/ci_sock/part_one/” as user is logout form the site.

  19. I am begginer with CI

    I get this message after installation.

    Not Found
    The requested URL /ci_sock/part_one/index.php/login/login_user was not found on this server.

    Need help. thx

  20. I downloaded and installed/tested CI 2.1.4.

    I would like to use the your project starter, but how do I know which of the standard files that come with with CI are different in your project starter.

    I assume files such as routes, database and config are different as well as new files you have added for the project. Any suggestions how updates can be made easy when CI updates to new versions?

    Should I just use diff? How do I know if changes were made by you or CI?

    Thanks

  21. @wyatt: I did not change any of the core codeigniter files, so upgrading should not be a problem. Check the CodeIgniter documentation and release notes for any possible breaking changes.

    Also, I do not recommend using this as a ‘starter’ project though, as it is just meant to be a quick example which leads up to Part 2 and Part 3 of the series, which really deals with using Socket.IO.

    If you need production-ready user login and authorization, you will be much better off using a more robust package like those I’ve mentioned before:
    Auth Me: https://github.com/gilbitron/CodeIgniter-Authme
    Flexi Auth: http://haseydesign.com/flexi-auth/
    ION Auth: https://github.com/benedmunds/CodeIgniter-Ion-Auth

  22. Hi,
    thanks for sharing this simple CI project, it’s helping me getting started with CI.

    Where can I find more small and simple CI projects just like this ?

    thanks.

  23. this redirect(‘/main/show_main’); works fine in my win apache
    but produce 500 internal server error on my unix web hosting
    aby idea how to fix this?

  24. I am getting the following error while running http://localhost/ci_stock/part_three
    A PHP Error was encountered

    Severity: Notice

    Message: Undefined index: config

    Filename: core/Loader.php

    Line Number: 1140

    An Error Was Encountered

    Could not connect to Redis at localhost:1234

  25. In your application when the admin logs out, if he press the back button in the browser it takes him to the dashboard. Do you have any suggestions on how to solve this issue???

  26. interesting,thank’s for sharing

  27. Thank you Eric for sharing.

  28. Hi,

    Thanks man for awesome project to get me started on codeigniter and web framework. I was having the same question as @raf, is there any other project that I can start with to work with codeigniter?

  29. Glad you liked it. I’m not sure about any other tutorials. I no longer work with CodeIgniter, but a good place to check/ask would be the official CodeIgniter forums: http://ellislab.com/forums

  30. Hi,

    We are experiencing some problems with the script, we are testing right now and receive the follow error when try login:

    [11-May-2014 00:43:37 UTC] PHP Fatal error:  Call to a member function delete() on a non-object in /home/ci_sock/part_three/application/libraries/MY_Session.php on line 260

    Just cloned from Git and changed the database config, the php version are 5.4.4 in debian, and the Redis server are hosted on Redislabs.

  31. A Database Error Occurred

    Error Number: 1046

    No database selected

    INSERT INTO `ci_sessions` (`session_id`, `ip_address`, `user_agent`, `last_activity`, `user_data`) VALUES (‘38786a4d46b921c74f92811292474da2’, ‘192.168.1.94’, ‘Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:28.0) Gecko/20100101 Firefox/28.0’, 1400247479, ”)

    Filename: libraries/Session.php

    Line Number: 328

    I have given host name ,username, password, dbname for part one, but still i get this error can any one help me pls

  32. There isLoggedIn in the session data. This variable is not part of your columns in the user table. Is it a Codeigniter session variable?

  33. afkhsahhf

  34. Hi.. I tried to post message.. But posting message is not working in this code.. Can you help me to resolve this..?

  35. Did you get any error messages? Anything show up in your PHP logs?
    Also, this post is quite old, and newer version of CodeIgniter may not be compatible.

  36. Happy Chhor Lyheang

    August 21, 2014 at 1:33 am

    it is not work on function redirect to home page

  37. Thanks for sharin. This is a great tutorial for start learning many “CodeIgniter tools” at the same time.

  38. Hi,
    thanks for sharing this wonderfull tuto !
    It’s exactly what I need.
    Could you help me with phpredis.
    I understand he part about CI and JS.
    But I’m a virgin regarding the part II.
    It’s my first time with Debian.
    So I set up a virtual machine with debian, install samba to get a share folder in windows, then I set up redis, then phpredis then restart apache2 (and the VM to be sure).
    I configured part three (config.php, database…).
    I created 2 users in team 1 to test it. But when I post something, the system doens’t work.
    I’m forced to reload the page to get the post.
    I think the problem should come from my redis/phpredis installation.
    After having done everything under debian
    Should I setup something in codeigniter to make it run?
    Something like files for redis and phpredis?
    Something to past in the CI folder?

    Please help me :)

  39. You should never compare passwords in an SQL query. Never trust user input! Therefore you really should be pulling the password down and comparing in code.

  40. Hi Eric,
    juste a message to tell you that these links are down:
    Part 1: You are here.
    Part 2: Use Redis instead of MySQL for CodeIgniter Session Data
    Part 3: Live Updates in CodeIgniter with Socket.IO and Redis
    the first for exemple points to :
    https://ericterpstra.com/2013/03/a-sample-codeigniter-application-with-login-and-session/
    The given page is a 404 Error.
    It should point to:
    https://ericterpstra.com/a-sample-codeigniter-application-with-login-and-session/
    Without “2013/03”.
    Hope it could be helpfull for you.
    Thank you for your share. It helps me a lot.
    And sorry for my bad english :)
    Kind regards.

  41. when clicking back after user is logged out still goes back to the page. so session is not destroyed. please fix this.. it would be great

  42. always i used to read smaller articles or reviews that as well clear their motive,
    and that is also happening with this article which I am reading at this time.

  43. FYI, in the update note at the top of your post you say that this is the third part in the series, when it is actually the first.

  44. ドこの上のスパムジレンマ あなたがした ブログを;私もブロガーだ、と私はあなたの状況を知りたいました。我々は生産さしているいくつかの良い 他と戦略を交換する興味があれば電子メール|私にEメールを撮影する自信を持って。 コンテンツ素材コンテンツ

  45. Hi,
    Its very nice tutorial.
    But I guess sessions are not applicable, when we click browser back button after logout action, dashboard page shouldn’t display.
    Kindly could you look into it.

    Thanks
    Phaneendra

  46. 友達のFacebookのリンクからサイトを発見、それはあなたがファン層を成長させてきたと私は今、なぜスーパー有益な記事をundertsand、感謝万人と思われます。

  47. はあなた、あなたのブログがこの素晴らしいを見せていた方法上の任意のヒントを使用して、メッセージを私にでし新しい投稿上にチェックするためにすぐに戻ってくる楽しむことを知らせる前に、あなたのウェブサイトを残しcouldntの、私は感謝するだろう!

  48. Hey its awesome.

  49. Hey Eric, thanks for the informative article, was valuable for some testing. But I thought it’s worthwhile pointing out that the demo application is vulnerable to several XSS attacks. Happy to share details directly with you.

Leave a Reply

Your email address will not be published.

*

© 2018 Eric Terpstra

Theme by Anders NorénUp ↑