Creating a Login and Registration Form using CodeIgniter 4 Tutorial

In this tutorial, this tutorial can help you to create a Login and Registration using PHP's CodeIgniter 4 Framework. The tutorial aims to provide students and new programmers with a reference for learning to code for developing web applications using CodeIgniter 4. Here, I will be providing the scripts of a simple web application with a Login and Registration feature.

What is the Login and Registration Form?

The Login and Registration Form is one of the most common security features of a website or web application. Users must input the necessary information in the login form in order to access the specific website or pages. The section with a combination of input fields is the same as the Registration form, and users must fill it up with information to generate a login ID and password.

How to Create Login and Registration Form in CodeIgniter 4?

The Login and Registration Form can be developed in Codeigniter 4 easily by creating a Login and Registration model, controllers, and views. To give you a better idea of how to achieve this, check out the scripts and instructions below for creating a simple web application with a Login and Registration feature.

Getting Started

Before we start the coding part, please make sure to download and install a virtual server such as XAMPP/WAMP on your local machine. After the successful installation, make sure to start the Apache and MySQL servers. Then download CodeIgniter 4 Framework and place it in htdocs directory for XAMPP and www for WAMP. Visit the official documentation site for installation instructions for Codeigniter 4 framework.

Create the App Database

Browse the PHPMyAdmin [http://localhost/phpmyadmin] in your prefered browser and create a new database named login_db.

Setup .env Variables

Create the App Database

Next, setup the database credentials in Codeigniter .env file. The file is located in the root folder of your CI4 project.

  1. #--------------------------------------------------------------------
  2. # DATABASE
  3. #--------------------------------------------------------------------
  4.  
  5. database.default.hostname = localhost
  6. database.default.database = login_db
  7. database.default.username = root
  8. database.default.password =
  9. database.default.DBDriver = MySQLi
  10. database.default.DBPrefix =

Setup Base URL

Next, update your project's base URL variable located in the app/Config/App.php.

  1. <?php
  2. public $baseURL = 'http://localhost/ci4-login-registration';

Create DB Table

Next, let's create the user table of the application. To do that we can use the CI4 spark's migrations. Follow the step below:

  1. Open your terminal or command prompt and redirect the working directory to your project's root folder.
  2. Run php spark make:migration User to generate a Migration file for User Table. The file will be inserted inside the App>Database>Migrations with the filename format YYYY-mm-dd-#####_Users.php.
  3. Then, paste the following script.
    1. <?php
    2.  
    3. namespace App\Database\Migrations;
    4.  
    5. use CodeIgniter\Database\Migration;
    6.  
    7. class Users extends Migration
    8. {
    9. public function up()
    10. {
    11. $this->forge->addField([
    12. 'id' => [
    13. 'type' => 'INT',
    14. 'constraint' => 30,
    15. 'unsigned' => true,
    16. 'auto_increment' => true,
    17. ],
    18. 'firstname' => [
    19. 'type' => 'VARCHAR',
    20. 'constraint' => '250',
    21. ],
    22. 'middlename' => [
    23. 'type' => 'VARCHAR',
    24. 'constraint' => '250',
    25. 'null' => true,
    26. 'default' => null
    27. ],
    28. 'lastname' => [
    29. 'type' => 'VARCHAR',
    30. 'constraint' => '250',
    31. ],
    32. 'email' => [
    33. 'type' => 'TEXT',
    34. ],
    35. 'password' => [
    36. 'type' => 'TEXT',
    37. ],
    38. 'created_at datetime default current_timestamp',
    39. 'updated_at datetime default current_timestamp on update current_timestamp'
    40. ]);
    41. $this->forge->addKey('id', true);
    42. $this->forge->createTable('users');
    43. }
    44.  
    45. public function down()
    46. {
    47. //
    48. $this->forge->dropTable('users');
    49. }
    50. }
    51.  
    52.  
  4. Lastly, run or execute php spark migrate in your command prompt to create the database folder.

After the successful migration, a new table named users will be added to the database.

Creating the Model

Next, let's create the login or users table model. Follow the instruction below.

  1. Open your terminal or command prompt and redirect the working directory to your project's root folder.
  2. Run php spark make:model LoginModel to generate a Model file for User Table. The file will be inserted inside the App>Models
  3. Then, paste the following script.
    1. <?php
    2. namespace App\Models;
    3.  
    4. use CodeIgniter\Model;
    5.  
    6. class LoginModel extends Model
    7. {
    8. protected $DBGroup = 'default';
    9. protected $table = 'users';
    10. protected $primaryKey = 'id';
    11. protected $useAutoIncrement = true;
    12. protected $insertID = 0;
    13. protected $returnType = 'array';
    14. protected $useSoftDeletes = false;
    15. protected $protectFields = true;
    16. protected $allowedFields = ['firstname', 'middlename', 'lastname', 'email', 'password'];
    17.  
    18. // Dates
    19. protected $useTimestamps = false;
    20. protected $dateFormat = 'datetime';
    21. protected $createdField = 'created_at';
    22. protected $updatedField = 'updated_at';
    23. protected $deletedField = 'deleted_at';
    24.  
    25. // Validation
    26. protected $validationRules = [];
    27. protected $validationMessages = [];
    28. protected $skipValidation = false;
    29. protected $cleanValidationRules = true;
    30.  
    31. // Callbacks
    32. protected $allowCallbacks = true;
    33. protected $beforeInsert = [];
    34. protected $afterInsert = [];
    35. protected $beforeUpdate = [];
    36. protected $afterUpdate = [];
    37. protected $beforeFind = [];
    38. protected $afterFind = [];
    39. protected $beforeDelete = [];
    40. protected $afterDelete = [];
    41. }
    42.  

Creating the Controller

Next, let's create the login/registration and main/home page controllers. The controllers will be generated inside the App>Controllers directory.

  1. Execute php spark make:controller LoginController and follow the script below.
    1. <?php
    2.  
    3. namespace App\Controllers;
    4.  
    5. use App\Controllers\BaseController;
    6. use App\Models\LoginModel;
    7.  
    8. class LoginController extends BaseController
    9. {
    10. protected $request;
    11. protected $loginModel;
    12.  
    13. public function __construct()
    14. {
    15. $this->request = \Config\Services::request();
    16. $this->loginModel = new LoginModel;
    17. }
    18. public function index()
    19. {
    20. $data=[];
    21. $data['page_title']="Login";
    22. $data['data']=$this->request;
    23. $session = session();
    24. if($this->request->getMethod() == 'post'){
    25. $user = $this->loginModel->where('email', $this->request->getPost('email'))->first();
    26. if($user){
    27. $verify_password = password_verify($this->request->getPost('password'),$user['password']);
    28. if($verify_password){
    29. foreach($user as $k => $v){
    30. $session->set('login_'.$k, $v);
    31. }
    32. return redirect()->to('/Main');
    33. }else{
    34. $session->setFlashdata('error','Incorrect Password');
    35. }
    36. }else{
    37. $session->setFlashdata('error','Incorrect Email or Password');
    38. }
    39. }
    40. $data['session'] = $session;
    41. return view('login/login', $data);
    42. }
    43. public function logout(){
    44. $session = session();
    45. $session->destroy();
    46. return redirect()->to('/');
    47. }
    48.  
    49. public function registration(){
    50. $session = session();
    51. $data=[];
    52. $data['session'] = $session;
    53. $data['data'] = $this->request;
    54. $data['page_title'] = "Registration";
    55. if($this->request->getMethod() == 'post'){
    56. $firstname = $this->request->getPost('firstname');
    57. $middlename = $this->request->getPost('middlename');
    58. $lastname = $this->request->getPost('lastname');
    59. $email = $this->request->getPost('email');
    60. $password = $this->request->getPost('password');
    61. $checkEmail = $this->loginModel->where('email', $email)->countAllResults();
    62. if($checkEmail > 0){
    63. $session->setFlashdata('error','Email is already taken.');
    64. }else{
    65. $idata = [
    66. 'firstname' => $firstname,
    67. 'middlename' => $middlename,
    68. 'lastname' => $lastname,
    69. 'email' => $email,
    70. 'password' => password_hash($password, PASSWORD_DEFAULT),
    71. ];
    72. $save = $this->loginModel->save($idata);
    73. if($save){
    74. $session->setFlashdata('success','Your Account has been registered sucessfully.');
    75. return redirect()->to('/');
    76. }
    77. }
    78. }
    79. return view('login/registration', $data);
    80. }
    81. }
    82.  
    83.  
  2. Execute php spark make:controller Main and follow the script below.
    1. <?php
    2.  
    3. namespace App\Controllers;
    4. use App\Models\Auth;
    5. class Main extends BaseController
    6. {
    7. protected $request;
    8.  
    9. public function __construct()
    10. {
    11. $this->request = \Config\Services::request();
    12. $this->session = session();
    13. $this->auth_model = new Auth;
    14. $this->data = ['session' => $this->session];
    15. }
    16.  
    17. public function index()
    18. {
    19. $this->data['page_title']="Home";
    20. return view('pages/home', $this->data);
    21. }
    22.  
    23. public function users(){
    24. if($this->session->login_type != 1){
    25. throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
    26. }
    27. $this->data['page_title']="Users";
    28. $this->data['page'] = !empty($this->request->getVar('page')) ? $this->request->getVar('page') : 1;
    29. $this->data['perPage'] = 10;
    30. $this->data['total'] = $this->auth_model->where("id != '{$this->session->login_id}'")->countAllResults();
    31. $this->data['users'] = $this->auth_model->where("id != '{$this->session->login_id}'")->paginate($this->data['perPage']);
    32. $this->data['total_res'] = is_array($this->data['users'])? count($this->data['users']) : 0;
    33. $this->data['pager'] = $this->auth_model->pager;
    34. return view('pages/users/list', $this->data);
    35. }
    36. public function user_edit($id=''){
    37. if($this->session->login_type != 1){
    38. throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
    39. }
    40. if(empty($id))
    41. return redirect()->to('Main/users');
    42. if($this->request->getMethod() == 'post'){
    43. extract($this->request->getPost());
    44. if($password !== $cpassword){
    45. $this->session->setFlashdata('error',"Password does not match.");
    46. }else{
    47. $udata= [];
    48. $udata['name'] = $name;
    49. $udata['email'] = $email;
    50. $udata['type'] = $type;
    51. $udata['status'] = $status;
    52. if(!empty($password))
    53. $udata['password'] = password_hash($password, PASSWORD_DEFAULT);
    54. $update = $this->auth_model->where('id',$id)->set($udata)->update();
    55. if($update){
    56. $this->session->setFlashdata('success',"User Details has been updated successfully.");
    57. return redirect()->to('Main/user_edit/'.$id);
    58. }else{
    59. $this->session->setFlashdata('error',"User Details has failed to update.");
    60. }
    61. }
    62. }
    63.  
    64. $this->data['page_title']="Users";
    65. $this->data['user'] = $this->auth_model->where("id ='{$id}'")->first();
    66. return view('pages/users/edit', $this->data);
    67. }
    68.  
    69. public function user_delete($id=''){
    70. if($this->session->login_type != 1){
    71. throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
    72. }
    73. if(empty($id)){
    74. $this->session->setFlashdata('main_error',"user Deletion failed due to unknown ID.");
    75. return redirect()->to('Main/users');
    76. }
    77. $delete = $this->auth_model->where('id', $id)->delete();
    78. if($delete){
    79. $this->session->setFlashdata('main_success',"User has been deleted successfully.");
    80. }else{
    81. $this->session->setFlashdata('main_error',"user Deletion failed due to unknown ID.");
    82. }
    83. return redirect()->to('Main/users');
    84. }
    85. }
    86.  

Creating the Page Layouts

On the App>Views directory create a new directory named layouts. Then, add new PHP files like the following.

login_base.php

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <meta charset="UTF-8">
  4. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title><?= isset($page_title) ? $page_title.' | ' : "" ?><?= env('system_name') ?></title>
  7.  
  8. <link rel="preconnect" href="https://fonts.googleapis.com">
  9. <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  10. <!-- Font Awesome -->
  11. <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css" integrity="sha512-KfkfwYDsLkIlwQp6LFnl8zNdLGxu9YAA1QvwINks4PhcElQSvqcyVLLD9aMhXd13uQjoXtEKNosOWaZqXgel0g==" crossorigin="anonymous" referrerpolicy="no-referrer" />
  12. <!-- Bootstrap -->
  13. <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
  14.  
  15. <link rel="stylesheet" href="<?= base_url('public/assets/css/styles.css') ?>">
  16.  
  17. <!-- Font Awesome -->
  18. <script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/js/all.min.js" integrity="sha512-6PM0qYu5KExuNcKt5bURAoT6KCThUmHRewN3zUFNaoI6Di7XJPTMoT6K0nsagZKk2OB4L7E3q1uQKHNHd4stIQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
  19.  
  20. <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
  21. <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
  22. html, body{
  23. height:100%;
  24. width:100%;
  25. }
  26. body{
  27. display:flex;
  28. flex-direction:row;
  29. align-items:center;
  30. justify-content:center;
  31. }
  32. </style>
  33. </head>
  34. <body class="bg-dark bg-gradient bg-opacity-25">
  35. <?= $this->renderSection('content') ?>
  36. </body>
  37. <?= $this->renderSection('custom_js') ?>
  38. </html>

main.php

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title><?= isset($page_title) ? $page_title.' | ' : "" ?><?= env('system_name') ?></title>
  8.  
  9. <link rel="preconnect" href="https://fonts.googleapis.com">
  10. <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  11. <!-- Font Awesome -->
  12. <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css" integrity="sha512-KfkfwYDsLkIlwQp6LFnl8zNdLGxu9YAA1QvwINks4PhcElQSvqcyVLLD9aMhXd13uQjoXtEKNosOWaZqXgel0g==" crossorigin="anonymous" referrerpolicy="no-referrer" />
  13. <!-- Bootstrap -->
  14. <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
  15.  
  16. <link rel="stylesheet" href="<?= base_url('public/assets/css/styles.css') ?>">
  17.  
  18. <!-- Font Awesome -->
  19. <script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/js/all.min.js" integrity="sha512-6PM0qYu5KExuNcKt5bURAoT6KCThUmHRewN3zUFNaoI6Di7XJPTMoT6K0nsagZKk2OB4L7E3q1uQKHNHd4stIQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
  20.  
  21. <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
  22. <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
  23.  
  24. </head>
  25. <body class="bg-dark bg-gradient bg-opacity-25">
  26. <?= $this->renderSection('content') ?>
  27. </body>
  28. <?= $this->renderSection('custom_js') ?>
  29. </html>

Creating the Custom Stylesheet

Create a new CSS file on the public>css> and name it as styles.css

  1. @import url('https://fonts.googleapis.com/css2?family=Secular+One&display=swap');
  2. :root{
  3. --secular-font: 'Secular One', sans-serif;
  4. }
  5. html,
  6. body{
  7. height: 100%;
  8. width: 100%;
  9. margin: unset;
  10. }
  11. /* Login Wrapper */
  12. #login-wrapper {
  13. position: relative;
  14. height: 100%;
  15. width: 100%;
  16. background: #000;
  17. overflow-x: hidden;
  18. z-index: 0;
  19. }
  20. #login-wrapper::before {
  21. content: "";
  22. position: absolute;
  23. left: -165px;
  24. top: 0;
  25. background: #000000e7;
  26. width: 70%;
  27. height: 100%;
  28. transform: skewX(9deg);
  29. z-index: 2;
  30. opacity: .8;
  31. }
  32. #login-wrapper:after {
  33. content: "";
  34. position: absolute;
  35. left: 50%;
  36. top: 0;
  37. background: #fff;
  38. width: 70%;
  39. height: 100%;
  40. transform: skewX(9deg);
  41. z-index: 1;
  42.  
  43. }
  44. #login-wrapper>div{
  45. position: relative;
  46. z-index: 3;
  47. height: 100%;
  48. overflow-y: auto;
  49. overflow-x: hidden;
  50. padding: 2em 0.5em;
  51. }
  52. #login-wrapper .login-title{
  53. font-size: 2.3rem;
  54. font-family: var(--secular-font);
  55. letter-spacing: 3px;
  56. font-weight: 600;
  57. }
  58. #login-wrapper .sub-title{
  59. font-size: 1rem;
  60. font-family: var(--secular-font);
  61. color:#dad8d8;
  62. }
  63.  
  64. /* Main Page Wrapper */
  65. #main-wrapper{
  66. position: relative;
  67. height: 100%;
  68. width: 100%;
  69. background: #fff;
  70. overflow-x: hidden;
  71. z-index: 0;
  72. }
  73.  
  74. #main-wrapper:before {
  75. content: "";
  76. position: absolute;
  77. width: 100%;
  78. top: -60px;
  79. height: 320px;
  80. background: #000000;
  81. transform: skewY(5deg);
  82. z-index: 2;
  83. }
  84. #main-wrapper:after {
  85. content: "";
  86. position: absolute;
  87. width: 100%;
  88. top: 5px;
  89. height: 320px;
  90. background: #000000;
  91. transform: skewY(5deg);
  92. z-index: 1;
  93. opacity: .6;
  94. }
  95. #content-wrapper{
  96. position: relative;
  97. z-index:4;
  98. padding: 0 3em;
  99. }
  100. #main-wrapper .page-title{
  101. font-size: 2.3rem;
  102. font-family: var(--secular-font);
  103. letter-spacing: 3px;
  104. font-weight: 600;
  105. }
  106. #main-wrapper .sub-title{
  107. font-size: 1rem;
  108. font-family: var(--secular-font);
  109. color:#dad8d8;
  110. }
  111. #main-wrapper .title-container{
  112. width: 100%;
  113. height: 320px;
  114. margin-bottom: 50px;
  115. }

Creating the Pages Content

Next, let's create the login form, registration form, and home page content. On the App>Views directory add 2 new folders named login and pages. Then create the following PHP file scripts.

login/login.php

  1. <?= $this->extend('layouts/login_base') ?>
  2.  
  3. <?= $this->section('content') ?>
  4. <div id="login-wrapper">
  5. <div>
  6. <div class="row mx-0 justify-content-between align-items-center" style="min-height:100%">
  7. <div class="col-6">
  8. <div class="login-title text-light text-center">Welcome to Sample Website</div>
  9. <div class="sub-title text-center">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</div>
  10. </div>
  11. <div class="col-6">
  12. <div class="login-title text-center">Login to Sample Site</div>
  13. <hr class="mx-auto border 2 opacity-100 border-dark" style="height:2px; width:25px">
  14. <div class="col-lg-9 col-md-10 col-sm-12 col-12 mx-auto mt-3">
  15. <div class="card shadow rounded-0">
  16. <div class="card-body rounded-0">
  17. <div class="container-fluid">
  18. <form action="<?= base_url('login') ?>" id="login-form" method="POST">
  19. <?php if($session->getFlashdata('error')): ?>
  20. <div class="alert alert-danger rounded-0 py-1 px-2 mb-3">
  21. <?= $session->getFlashdata('error') ?>
  22. </div>
  23. <?php endif; ?>
  24. <?php if($session->getFlashdata('success')): ?>
  25. <div class="alert alert-success rounded-0 py-1 px-2 mb-3">
  26. <?= $session->getFlashdata('success') ?>
  27. </div>
  28. <?php endif; ?>
  29. <div class="mb-3">
  30. <label for="email" class="form-label tex-body">Email</label>
  31. <input type="email" class="form-control rounded-0" id="email" name="email" required="required" placeholder="[email protected]">
  32. </div>
  33. <div class="mb-3">
  34. <label for="password" class="form-label tex-body">Password</label>
  35. <input type="password" class="form-control rounded-0" id="password" name="password" required="required" placeholder="*******">
  36. </div>
  37. <div class="mb-3">
  38. <span class="text-body fw-light"><small>Don't have an Account yet?</small></span>
  39. <span><a href="<?= base_url('registration') ?>"><small>Register Here</small></a></span>
  40. </div>
  41. <div class="mb-3">
  42. <div class="col-lg-6 col-md-6 col-sm-12 col-12 mx-auto">
  43. <button class="btn btn-dark bg-gradient rounded-pill w-100 fw-bolder">Login</button>
  44. </div>
  45. </div>
  46. </form>
  47. </div>
  48. </div>
  49. </div>
  50. </div>
  51. </div>
  52. </div>
  53. </div>
  54. </div>
  55. <?= $this->endSection() ?>

login/registration.php

  1. <?= $this->extend('layouts/login_base') ?>
  2.  
  3. <?= $this->section('content') ?>
  4. <div id="login-wrapper">
  5. <div>
  6. <div class="row mx-0 justify-content-between align-items-center">
  7. <div class="col-6">
  8. <div class="login-title text-light text-center">Welcome to Sample Website</div>
  9. <div class="sub-title text-center">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</div>
  10. </div>
  11. <div class="col-6">
  12. <div class="login-title text-center">Create an Account</div>
  13. <hr class="mx-auto border 2 opacity-100 border-dark" style="height:2px; width:25px">
  14. <div class="col-lg-9 col-md-10 col-sm-12 col-12 mx-auto mt-3" style="min-height:100%">
  15. <div class="card shadow rounded-0">
  16. <div class="card-body rounded-0">
  17. <div class="container-fluid">
  18. <form action="" id="login-form" method="POST">
  19. <?php if($session->getFlashdata('error')): ?>
  20. <div class="alert alert-danger rounded-0 mb-3">
  21. <?= $session->getFlashdata('error') ?>
  22. </div>
  23. <?php endif; ?>
  24. <?php if($session->getFlashdata('success')): ?>
  25. <div class="alert alert-success rounded-0 mb-3">
  26. <?= $session->getFlashdata('success') ?>
  27. </div>
  28. <?php endif; ?>
  29. <div class="mb-3">
  30. <label for="firstname" class="form-label tex-body">First Name</label>
  31. <input type="firstname" class="form-control rounded-0" id="firstname" name="firstname" required="required" placeholder="Mark">
  32. </div>
  33. <div class="mb-3">
  34. <label for="middlename" class="form-label tex-body">Middle Name</label>
  35. <input type="middlename" class="form-control rounded-0" id="middlename" name="middlename"placeholder="optional">
  36. </div>
  37. <div class="mb-3">
  38. <label for="lastname" class="form-label tex-body">Last Name</label>
  39. <input type="lastname" class="form-control rounded-0" id="lastname" name="lastname" required="required" placeholder="Cooper">
  40. </div>
  41. <div class="mb-3">
  42. <label for="email" class="form-label tex-body">Email</label>
  43. <input type="email" class="form-control rounded-0" id="email" name="email" required="required" placeholder="[email protected]">
  44. </div>
  45. <div class="mb-3">
  46. <label for="password" class="form-label tex-body">Password</label>
  47. <input type="password" class="form-control rounded-0" id="password" name="password" required="required" placeholder="*******">
  48. </div>
  49. <div class="mb-3">
  50. <span class="text-body fw-light"><small>Already have an Account?</small></span>
  51. <span><a href="<?= base_url() ?>"><small>Login Here</small></a></span>
  52. </div>
  53. <div class="mb-3">
  54. <div class="col-lg-6 col-md-6 col-sm-12 col-12 mx-auto">
  55. <button class="btn btn-dark bg-gradient rounded-pill w-100 fw-bolder">Login</button>
  56. </div>
  57. </div>
  58. </form>
  59. </div>
  60. </div>
  61. </div>
  62. </div>
  63. </div>
  64. </div>
  65. </div>
  66. </div>
  67. <?= $this->endSection() ?>

pages/home.php

  1. <?= $this->extend('layouts/main') ?>
  2.  
  3. <?= $this->section('content') ?>
  4. <div id="main-wrapper">
  5. <div id="content-wrapper">
  6. <div class="title-container d-flex flex-column justify-content-center align-items-center">
  7. <div class="page-title text-center text-light">Sample Website Only</div>
  8. <div class="sub-title text-center">Welcome back <?= ucwords($session->get('login_firstname')." " . $session->get('login_lastname')) ?>!</div>
  9. </div>
  10. </div>
  11. <h2 class="text-center">Your Account Details</h2>
  12. <hr class="mx-auto border 2 opacity-100 border-dark" style="height:2px; width:25px">
  13. <div class="col-12 col-lg-4 col-md-6 col-sm-12 mx-auto mb-5">
  14. <div class="card rounded-0 mb-3">
  15. <div class="card-body rounded-0">
  16. <div class="container-fluid">
  17. <dl>
  18. <dt class="text-body">First Name:</dt>
  19. <dd class="ps-4"><?= $session->get('login_firstname') ?></dd>
  20. <dt class="text-body">Middle Name:</dt>
  21. <dd class="ps-4"><?= !empty($session->get('login_middlename')) ? $session->get('login_middlename') : "N/A" ?></dd>
  22. <dt class="text-body">Last Name:</dt>
  23. <dd class="ps-4"><?= $session->get('login_lastname') ?></dd>
  24. <dt class="text-body">Email:</dt>
  25. <dd class="ps-4"><?= $session->get('login_email') ?></dd>
  26. </dl>
  27. </div>
  28. </div>
  29. </div>
  30. <div class="col-lg-4 col-md-6 col-xs-12 col-12 mx-auto">
  31. <a href="<?= base_url('logout') ?>" class="btn btn-dark bg-gradient rounded-pill w-100">Logout</a>
  32. </div>
  33. </div>
  34.  
  35. </div>
  36. <?= $this->endSection() ?>

Managing the Routes

Lastly, let's manage the routes of the pages so we can test and check the result of this Login and Registration project using the CodeIgniter 4 Framework. Open the App>Config>Routes.php. Then follow the script below.

  1. <?php
  2.  
  3. namespace Config;
  4.  
  5. // Create a new instance of our RouteCollection class.
  6. $routes = Services::routes();
  7.  
  8. // Load the system's routing file first, so that the app and ENVIRONMENT
  9. // can override as needed.
  10. if (is_file(SYSTEMPATH . 'Config/Routes.php')) {
  11. require SYSTEMPATH . 'Config/Routes.php';
  12. }
  13.  
  14. /*
  15.   * --------------------------------------------------------------------
  16.   * Router Setup
  17.   * --------------------------------------------------------------------
  18.   */
  19. $routes->setDefaultNamespace('App\Controllers');
  20. $routes->setDefaultController('LoginController');
  21. $routes->setDefaultMethod('index');
  22. $routes->setTranslateURIDashes(false);
  23. $routes->set404Override();
  24. // The Auto Routing (Legacy) is very dangerous. It is easy to create vulnerable apps
  25. // where controller filters or CSRF protection are bypassed.
  26. // If you don't want to define all routes, please use the Auto Routing (Improved).
  27. // Set `$autoRoutesImproved` to true in `app/Config/Feature.php` and set the following to true.
  28. //$routes->setAutoRoute(false);
  29.  
  30. /*
  31.   * --------------------------------------------------------------------
  32.   * Route Definitions
  33.   * --------------------------------------------------------------------
  34.   */
  35.  
  36. // We get a performance increase by specifying the default
  37. // route since we don't have to scan directories.
  38. $routes->get('/', 'LoginController::index',['filter' => 'authenticated']);
  39. $routes->get('/registration', 'LoginController::registration',['filter' => 'authenticated']);
  40. $routes->get('LoginController', 'LoginController::index',['filter' => 'authenticated']);
  41. $routes->get('LoginController/(:segment)', 'LoginController::$1',['filter' => 'authenticated']);
  42. $routes->match(['post'], '/registration', 'LoginController::registration',['filter' => 'authenticated']);
  43. $routes->match(['post'], '/login', 'LoginController::index',['filter' => 'authenticated']);
  44. $routes->get('/logout', 'LoginController::logout');
  45.  
  46. $routes->group('Main', ['filter'=>'authenticate'], static function($routes){
  47. $routes->get('', 'Main::index');
  48. $routes->get('(:segment)', 'Main::$1');
  49. $routes->get('(:segment)/(:any)', 'Main::$1/$2');
  50. $routes->match(['post'], 'user_edit/(:num)', 'Main::user_edit/$1');
  51. });
  52.  
  53.  
  54.  
  55. /*
  56.   * --------------------------------------------------------------------
  57.   * Additional Routing
  58.   * --------------------------------------------------------------------
  59.   *
  60.   * There will often be times that you need additional routing and you
  61.   * need it to be able to override any defaults in this file. Environment
  62.   * based routes is one such time. require() additional route files here
  63.   * to make that happen.
  64.   *
  65.   * You will have access to the $routes object within that file without
  66.   * needing to reload it.
  67.   */
  68. if (is_file(APPPATH . 'Config/' . ENVIRONMENT . '/Routes.php')) {
  69. require APPPATH . 'Config/' . ENVIRONMENT . '/Routes.php';
  70. }

There you go! You can now test the application on your browser by browsing http://localhost/ci4-login-registration. The application will be redirected to the login page by default. Users cannot access the main page if he/she is not registered and logged in to the application yet.

Snapshots

Here are the snapshots of the resulting interface of pages of the provided sample CI4 Project.

Login Page

Login and Registration using CI4

Registration Page

Login and Registration using CI4

Home Page

Login and Registration using CI4

I have also provided the complete source code of this Login and Registration using the CI4 project on this site and it is free to download. The download button is located below this tutorial's content. Free free to download and modify it.

I hope this Creating a Login and Registration Form using CodeIgniter 4 Tutorial will help you with what you are looking for and will be useful for your current and future CodeIgniter projects.

Explore more on this website for more Tutorials and Free Source Codes.

Happy Coding =)

Comments

Submitted byDana Good (not verified)on Fri, 07/28/2023 - 23:15

Hello, thank you for the tutorial and source code!
Submitted byspica (not verified)on Mon, 09/04/2023 - 10:41

I downloaded your code and after I click the login button i got an error Class "App\Models\Auth" not found any idea on how to fix that??
Submitted byAnonymous (not verified)on Thu, 05/02/2024 - 22:03

"App\Models\Auth" changes for "App\Models\LoginModel"

Add new comment