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):
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']['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:
- Clone the repo
- Set up the database and import the tables from cisock.sql
- 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:
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.
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.
$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.
// 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.
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
March 26, 2013 at 12:19 pm
Hi, what is the user and password for the DEMO?
March 26, 2013 at 11:26 pm
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.
May 17, 2013 at 6:04 am
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/
May 17, 2013 at 6:32 am
sorry, thanks. i figured it out. :)
May 19, 2013 at 7:28 am
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?
May 21, 2013 at 9:52 am
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 ?
May 21, 2013 at 7:38 pm
@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
June 11, 2013 at 3:47 am
Interesting post. pls how can i send invalid username or password message back to the login page?
June 20, 2013 at 9:50 am
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);
July 8, 2013 at 11:36 am
very good example of Code igniter session login.
July 10, 2013 at 3:56 am
Interesting code and app thanks for sharing
July 11, 2013 at 8:26 am
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
July 12, 2013 at 4:08 am
Can you please reply me?
July 12, 2013 at 12:29 pm
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.
July 16, 2013 at 9:11 am
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.
July 17, 2013 at 3:09 pm
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
July 18, 2013 at 4:02 am
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.
July 19, 2013 at 2:50 pm
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.
July 22, 2013 at 11:11 am
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
August 4, 2013 at 8:07 pm
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
August 4, 2013 at 9:38 pm
@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
August 12, 2013 at 9:36 am
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.
September 8, 2013 at 3:17 am
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?
September 21, 2013 at 2:45 am
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
September 21, 2013 at 5:34 am
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???
November 1, 2013 at 7:11 am
interesting,thank’s for sharing
December 10, 2013 at 12:20 am
Thank you Eric for sharing.
December 11, 2013 at 12:10 pm
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?
December 11, 2013 at 3:08 pm
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
May 10, 2014 at 7:45 pm
Hi,
We are experiencing some problems with the script, we are testing right now and receive the follow error when try login:
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.
May 16, 2014 at 8:39 am
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
June 25, 2014 at 3:43 pm
There isLoggedIn in the session data. This variable is not part of your columns in the user table. Is it a Codeigniter session variable?
July 13, 2014 at 3:14 am
sdf
July 26, 2014 at 2:24 am
afkhsahhf
August 14, 2014 at 6:06 am
Hi.. I tried to post message.. But posting message is not working in this code.. Can you help me to resolve this..?
August 14, 2014 at 5:03 pm
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.
August 21, 2014 at 1:33 am
it is not work on function redirect to home page
August 23, 2014 at 3:09 pm
Thanks for sharin. This is a great tutorial for start learning many “CodeIgniter tools” at the same time.
September 16, 2014 at 9:13 am
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 :)
September 19, 2014 at 12:41 am
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.
March 25, 2015 at 11:31 am
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.
April 27, 2015 at 10:10 am
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
June 2, 2015 at 2:04 pm
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.
June 25, 2015 at 11:54 am
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.
September 10, 2015 at 1:29 am
ドこの上のスパムジレンマ あなたがした ブログを;私もブロガーだ、と私はあなたの状況を知りたいました。我々は生産さしているいくつかの良い 他と戦略を交換する興味があれば電子メール|私にEメールを撮影する自信を持って。 コンテンツ素材コンテンツ
September 28, 2015 at 11:05 pm
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
October 5, 2015 at 7:03 pm
友達のFacebookのリンクからサイトを発見、それはあなたがファン層を成長させてきたと私は今、なぜスーパー有益な記事をundertsand、感謝万人と思われます。
November 14, 2015 at 11:17 am
はあなた、あなたのブログがこの素晴らしいを見せていた方法上の任意のヒントを使用して、メッセージを私にでし新しい投稿上にチェックするためにすぐに戻ってくる楽しむことを知らせる前に、あなたのウェブサイトを残しcouldntの、私は感謝するだろう!
December 1, 2015 at 1:09 am
Hey its awesome.
December 4, 2016 at 2:14 am
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.