In this tutorial you will learn how to create login and register using CodeIgniter 4.
Not only that,
I will also share with you how to use filters to control access on routes so that the application that will be built is safer without writing many lines of code.
(Step-by-Step)
Let's get started.
Step #1. CodeIgniter 4 Installation
To install CodeIgniter 4, you can do it in 2 ways: manual installation and installation via composer.
In this tutorial, I will be using a manual installation.
Please download the CodeIgniter 4 file at the following link:
Then extract it on your web server.
If you are using WAMPSERVER, extract it in the folder:
C:/wamp64/www
If you are using XAMPP, extract it in the folder:
C:/xampp/htdocs
In this tutorial, I am using XAMPP.
Then rename to "login" as shown below:
Then, open the project "login" folder using the code editor.
In this tutorial, I use "Visual Studio Code", you can use Sublime Text, PHP Storm, or any other code editor.
Step #2. Create a Database and Table
Create a new database on MySQL, you can use tools like SQLyog, PHPMyAdmin or similar tools.
Here I created a database with the name "login_db".
If you create a database with the same name that's even better.
To create a database with MySQL, it can be done by executing the following query:
CREATE DATABASE login_db;
The SQL command above will create a database with the name "login_db".
Next, create a table in the "login db" database.
Here I created a table with the name "users".
If you create a table with the same name that's even better.
To create a table "users", it can be done by executing the following SQL command:
CREATE TABLE users( user_id INT PRIMARY KEY AUTO_INCREMENT, user_name VARCHAR(100), user_email VARCHAR(100), user_password VARCHAR(200), user_created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ENGINE=INNODB;
The SQL command above, will create a table with the name "users" with fields: user_id, user_name, user_email, user_password, and user_created_at.
Step #3. Connect to Database
Next, make a connection between the database and the CodeIgniter project.
Find the env file in the project root, then rename it to .env and open the file.
Then find the following code:
# database.default.hostname = localhost # database.default.database = ci4 # database.default.username = root # database.default.password = root # database.default.DBDriver = MySQLi
Change it to be like the following:
database.default.hostname = localhost database.default.database = login_db database.default.username = root database.default.password = database.default.DBDriver = MySQLi
Next, find the following code:
# CI_ENVIRONMENT = production
Then change it to be like the following:
CI_ENVIRONMENT = development
That means you enter development mode, this mode will help you make it easier to track errors as you build your project.
Step #4. Create a Model File
In this tutorial, only one model file is needed, namely "UserModel.php".
Create a model file named "UserModel.php" in the "app/Models" folder, then type the following code:
<?php namespace App\Models; use CodeIgniter\Model; class UserModel extends Model{ protected $table = 'users'; protected $allowedFields = ['user_name','user_email','user_password','user_created_at']; }
Step #5. Create a Controller Register.php File
Create a controller file named "Register.php" in the "app/Controllers" folder, then type the following code:
<?php namespace App\Controllers; use CodeIgniter\Controller; use App\Models\UserModel; class Register extends Controller { public function index() { //include helper form helper(['form']); $data = []; echo view('register', $data); } public function save() { //include helper form helper(['form']); //set rules validation form $rules = [ 'name' => 'required|min_length[3]|max_length[20]', 'email' => 'required|min_length[6]|max_length[50]|valid_email|is_unique[users.user_email]', 'password' => 'required|min_length[6]|max_length[200]', 'confpassword' => 'matches[password]' ]; if($this->validate($rules)){ $model = new UserModel(); $data = [ 'user_name' => $this->request->getVar('name'), 'user_email' => $this->request->getVar('email'), 'user_password' => password_hash($this->request->getVar('password'), PASSWORD_DEFAULT) ]; $model->save($data); return redirect()->to('/login'); }else{ $data['validation'] = $this->validator; echo view('register', $data); } } }
In the "Register.php" controller above, there are two functions, namely: function index(), and function save().
Function index() to display a view called "register", while the function save() to save data to the "users" table in the database as well as encrypt passwords with the password_hash() method.
Step #6. Create a View register.php File
Create a view file named "register.php" in the "app/Views" folder, then type the following code:
<!doctype html> <html lang="en"> <head> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- Bootstrap CSS --> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha1/css/bootstrap.min.css" integrity="sha384-r4NyP46KrjDleawBgD5tp8Y7UzmLA05oM1iAEQ17CSuDqnUK2+k9luXQOfXJCJ4I" crossorigin="anonymous"> <title>Register</title> </head> <body> <div class="container"> <div class="row justify-content-md-center"> <div class="col-6"> <h1>Sign Up</h1> <?php if(isset($validation)):?> <div class="alert alert-danger"><?= $validation->listErrors() ?></div> <?php endif;?> <form action="/register/save" method="post"> <div class="mb-3"> <label for="InputForName" class="form-label">Name</label> <input type="text" name="name" class="form-control" id="InputForName" value="<?= set_value('name') ?>"> </div> <div class="mb-3"> <label for="InputForEmail" class="form-label">Email address</label> <input type="email" name="email" class="form-control" id="InputForEmail" value="<?= set_value('email') ?>"> </div> <div class="mb-3"> <label for="InputForPassword" class="form-label">Password</label> <input type="password" name="password" class="form-control" id="InputForPassword"> </div> <div class="mb-3"> <label for="InputForConfPassword" class="form-label">Confirm Password</label> <input type="password" name="confpassword" class="form-control" id="InputForConfPassword"> </div> <button type="submit" class="btn btn-primary">Register</button> </form> </div> </div> </div> <!-- Popper.js first, then Bootstrap JS --> <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha1/js/bootstrap.min.js" integrity="sha384-oesi62hOLfzrys4LxRF63OJCXdXDipiYWBnvTl9Y9/TRlw5xlKIEHpNyvvDShgf/" crossorigin="anonymous"></script> </body> </html>
In the “register.php” view, we call Bootstrap 5 CDN, both the CSS and JavaScript.
Visit the following URL for more info on Bootstrap 5:
In addition, there is also a form to register in the form of: input name, email, password, and Confirm password.
Step #7. Create a Controller Login.php File
Create a Controller file again named "Login.php" in the "app/Controllers" folder, then type the following code:
<?php namespace App\Controllers; use CodeIgniter\Controller; use App\Models\UserModel; class Login extends Controller { public function index() { helper(['form']); echo view('login'); } public function auth() { $session = session(); $model = new UserModel(); $email = $this->request->getVar('email'); $password = $this->request->getVar('password'); $data = $model->where('user_email', $email)->first(); if($data){ $pass = $data['user_password']; $verify_pass = password_verify($password, $pass); if($verify_pass){ $ses_data = [ 'user_id' => $data['user_id'], 'user_name' => $data['user_name'], 'user_email' => $data['user_email'], 'logged_in' => TRUE ]; $session->set($ses_data); return redirect()->to('/dashboard'); }else{ $session->setFlashdata('msg', 'Wrong Password'); return redirect()->to('/login'); } }else{ $session->setFlashdata('msg', 'Email not Found'); return redirect()->to('/login'); } } public function logout() { $session = session(); $session->destroy(); return redirect()->to('/login'); } }
In the "Login.php" controller above, there are three functions, namely: function index(), function auth(), and function logout().
The function index() is used to display a view named "login" which will display the login form.
The function auth() to perform authentication and set the session variable if the authentication is valid.
The function logout() to logout and destroy session variables.
Step #8. Create a View login.php File
Create a view file again named "login.php" in the "app/Views" folder, then type the following code:
<!doctype html> <html lang="en"> <head> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- Bootstrap CSS --> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha1/css/bootstrap.min.css" integrity="sha384-r4NyP46KrjDleawBgD5tp8Y7UzmLA05oM1iAEQ17CSuDqnUK2+k9luXQOfXJCJ4I" crossorigin="anonymous"> <title>Login</title> </head> <body> <div class="container"> <div class="row justify-content-md-center"> <div class="col-6"> <h1>Sign In</h1> <?php if(session()->getFlashdata('msg')):?> <div class="alert alert-danger"><?= session()->getFlashdata('msg') ?></div> <?php endif;?> <form action="/login/auth" method="post"> <div class="mb-3"> <label for="InputForEmail" class="form-label">Email address</label> <input type="email" name="email" class="form-control" id="InputForEmail" value="<?= set_value('email') ?>"> </div> <div class="mb-3"> <label for="InputForPassword" class="form-label">Password</label> <input type="password" name="password" class="form-control" id="InputForPassword"> </div> <button type="submit" class="btn btn-primary">Login</button> </form> </div> </div> </div> <!-- Popper.js first, then Bootstrap JS --> <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha1/js/bootstrap.min.js" integrity="sha384-oesi62hOLfzrys4LxRF63OJCXdXDipiYWBnvTl9Y9/TRlw5xlKIEHpNyvvDShgf/" crossorigin="anonymous"></script> </body> </html>
In the "login.php" view, we also call Bootstrap 5 CDN, both CSS and JavaScript.
In addition, there is also a login form in the form of: input email and password.
Step #9. Create a Controller Dashboard.php File
Apart from the “Register.php” and “Login.php” Controllers, create another Controller file called "Dashboard.php" in the "app/Controllers" folder.
Then type the following code:
<?php namespace App\Controllers; use CodeIgniter\Controller; class Dashboard extends Controller { public function index() { $session = session(); echo "Welcome back, ".$session->get('user_name'); } }
On the Controller "Dashboard.php" there is only one function, namely the function index() which functions to display the text "Welcome Back [login username]".
The purpose of this Controller is to protect it so that users cannot access the Dashboard without logging in.
That way, you will have a general idea of how to protect pages or routes from unauthorized users.
Step #10. Create a Filters Auth.php File
CodeIgniter 4 provides a filter feature that functions to handle Before Request or After Request.
This feature is very useful for handling checking or validating every request or few requests that are written with the same code.
It may sound complicated, but it's really not.
In this case, we will protect the function index() on the “Dashboard.php” Controller from users who have not logged in using Filter.
That way, you'll have a general idea of how the Filters work in CodeIgniter 4.
Create a filter file named "Auth.php" in the "app/Filters" folder, then type the following code:
<?php namespace App\Filters; use CodeIgniter\HTTP\RequestInterface; use CodeIgniter\HTTP\ResponseInterface; use CodeIgniter\Filters\FilterInterface; class Auth implements FilterInterface { public function before(RequestInterface $request, $arguments = null) { // if user not logged in if(! session()->get('logged_in')){ // then redirct to login page return redirect()->to('/login'); } } //-------------------------------------------------------------------- public function after(RequestInterface $request, ResponseInterface $response, $arguments = null) { // Do something here } }
In the "Auth.php" filter above, there are 2 functions, namely: function before() and function after().
In this case, we are only using the function before().
The before function, serves to validate the request before the request itself is executed.
In the "Auth.php" filter above, we redirect users to the login page if they access a page before logging in.
This can apply globally, in other words it applies to every request, or it can be for only a few requests.
In this case, we only use it to protect the "Dashboard.php" Controller.
So, we don't apply it globally, because we want the “Login.php” and “Register.php” controllers to be accessible without logging in.
Then open the "Filters.php" file located in the "app/Config" folder, then find the following code:
public $aliases = [ 'csrf' => \CodeIgniter\Filters\CSRF::class, 'toolbar' => \CodeIgniter\Filters\DebugToolbar::class, 'honeypot' => \CodeIgniter\Filters\Honeypot::class, ];
Then change it to be like this:
public $aliases = [ 'csrf' => \CodeIgniter\Filters\CSRF::class, 'toolbar' => \CodeIgniter\Filters\DebugToolbar::class, 'honeypot' => \CodeIgniter\Filters\Honeypot::class, 'auth' => \App\Filters\Auth::class, ];
In the code above, we add one additional line of code, namely "auth".
Next, open the "Routes.php" file located in the "app/Config" folder, then find the following code:
$routes->get('/', 'Home::index');
Then change it to be like the following:
$routes->get('/', 'Home::index'); $routes->get('/dashboard', 'Dashboard::index',['filter' => 'auth']);
In the code above, we add one route which is the dashboard which is protected by the previously created "auth" filter.
Now, if the user accesses the Dashboard without logging in, it will be automatically redirected to the Login page.
If you have other pages that you want to protect, just add them in the route and add the "auth" filter, so that these pages cannot be accessed before logging in without having to create a Filter file again.
Cool right?
Step #11. Testing
To ensure whether the application that is built runs well, test it by typing the following command in the Terminal or Command Prompt:
php spark serve
Like the following picture:
Next, visit the following URL to register a new user:
http://localhost:8080/register
If it goes well, a Sign Up form will appear as follows:
Then enter your Name, Email, Password, and Confirm Password, then click the "Register" button to register.
If the registration is successful, it will immediately be directed to the login form as follows:
Enter the previously registered Email and Password, then click the "Login" button to login.
If the login is successful, it will immediately be directed to the dashboard page as follows:
To logout, please access the following URL:
http://localhost:8080/login/logout
After logging out, please access the dashboard page to confirm whether the dashboard page can be accessed without logging in.
Visit the following URL to access the dashboard page:
http://localhost:8080/dashboard
If redirected back to the login page, then we have successfully protected the dashboard page from unauthorized users.
Conclusion:
The discussion this time is how to create a Login and Register using CodeIgniter 4.
Not only that, you have also learned how to set session variables using CodeIgniter 4, encrypt passwords, and protect routes using Filters.
So what are you waiting for, Let's Coding!
Download Source Code
Comments (9)
Swapnil Akolkar, 13 February 2021 18:39 -
Bro thanks but how to do logout ? I mean code for logout function I needed.
Swapnil Akolkar, 13 February 2021 18:41 -
Ohh sorry I got it its localhost/login/logout thanks
Viral, 17 February 2021 12:41 -
A good tutorial for a beginner..... :)
Yatin, 20 February 2021 16:44 -
Hi. it is very helpfull thank you
Angie Garner, 09 March 2021 07:29 -
Just want to say your article is as astonishing. The clearness on your post is just great and i can think you are an expert in this subject. Fine together with your permission allow me to grasp your feed to stay up to date with forthcoming post. Thank you 1,000,000 and please carry on the enjoyable work.
Kartik, 21 March 2021 21:25 -
Thank You for this post
kbs170, 12 April 2021 02:52 -
Great! Works as expected! I would like to set all pages protected as standard. Your solution is black list based: named pages are protected. I need a white list solution: named pages are public, e.g. login and register - the rest is protected. How can that work? best regards
kbs170, 19 April 2021 02:46 -
Very useful tutorial! Thanks
Sheikh Obydullah, 23 April 2021 18:39 -
Thank you so much. You explain middlewire (filter) easily. Anyway, could you recommend a wysiwyg editor for Codeigniter 4?