Codeigniter 4 Login and Registration Example
In this article, we will explain to you how to create a User Login logout and register example in Codeigniter 4(Codeigniter 4 Login and Registration Example). Sometimes when creating an admin panel at that time we need to Registration, Login, and log out to Codeigniter 4.
Overview
Step 1: Install Codeigniter 4
Step 2: Setting Database Configuration
Step 3: Create Table using migration
Step 4: Create Controllers and Model
Step 5: Create Custom Validation rules
Step 6: Creating a Filter
Step 7: Define The Route
Step 8: Create View Files
Step 9: Run Our Application
Install Codeigniter 4
If you want to download or install CodeIgniter 4 then you can below Url.
How To Install Codeigniter 4 Using Manual, Composer, Git
Setting Database Configuration
After complete installation of CodeIgniter 4. we have to database configuration. now we will open the .env file and change the database name, username, password in the .env file. See below changes in a .env file.
1 2 3 4 5 | database.default.hostname = localhost database.default.database = ci4_login database.default.username = root database.default.password = database.default.DBDriver = MySQLi |
Create Table using migration
Now, We need to migrate the users table. we can easily migrate the user table using the below command.
1 | php spark migrate |
Create Controllers and Model
we create the controllers and model. so you can see the below example.
app/Controllers/Login.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | <?php namespace App\Controllers; use App\Models\UserModel; class Login extends BaseController { public function index() { $data = []; helper(['form']); if ($this->request->getMethod() == 'post') { //let's do the validation here $rules = [ 'email' => 'required|min_length[6]|max_length[50]|valid_email', 'password' => 'required|min_length[8]|max_length[255]|validateUser[email,password]', ]; $errors = [ 'password' => [ 'validateUser' => 'Email or Password don\'t match' ] ]; if (! $this->validate($rules, $errors)) { $data['validation'] = $this->validator; }else{ $model = new UserModel(); $user = $model->where('email', $this->request->getVar('email')) ->first(); $this->setUserSession($user); //$session->setFlashdata('success', 'Successful Registration'); return redirect()->to('dashboard'); } } return view('login',$data); } private function setUserSession($user){ $data = [ 'id' => $user['id'], 'firstname' => $user['firstname'], 'lastname' => $user['lastname'], 'email' => $user['email'], 'isLoggedIn' => true, ]; session()->set($data); return true; } public function register(){ $data = []; helper(['form']); if ($this->request->getMethod() == 'post') { //let's do the validation here $rules = [ 'firstname' => 'required|min_length[3]|max_length[20]', 'lastname' => 'required|min_length[3]|max_length[20]', 'email' => 'required|min_length[6]|max_length[50]|valid_email|is_unique[users.email]', 'password' => 'required|min_length[8]|max_length[255]', 'password_confirm' => 'matches[password]', ]; if (! $this->validate($rules)) { $data['validation'] = $this->validator; }else{ $model = new UserModel(); $newData = [ 'firstname' => $this->request->getVar('firstname'), 'lastname' => $this->request->getVar('lastname'), 'email' => $this->request->getVar('email'), 'password' => $this->request->getVar('password'), ]; $model->save($newData); $session = session(); $session->setFlashdata('success', 'Successful Registration'); return redirect()->to('/'); } } return view('register',$data); } public function logout(){ session()->destroy(); return redirect()->to('/'); } //-------------------------------------------------------------------- } |
And second, we need to update the LoginController.php file. so you can follow the below code.
app/Controllers/Dashboard.php
1 2 3 4 5 6 7 8 9 10 11 | <?php namespace App\Controllers; class Dashboard extends BaseController { public function index() { $data = []; return view('dashboard', $data); } } |
app/Models/UserModel.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | <?php namespace App\Models; use CodeIgniter\Model; class UserModel extends Model{ protected $table = 'users'; protected $allowedFields = ['firstname', 'lastname', 'email', 'password', 'updated_at']; protected $beforeInsert = ['beforeInsert']; protected $beforeUpdate = ['beforeUpdate']; protected function beforeInsert(array $data){ $data = $this->passwordHash($data); $data['data']['created_at'] = date('Y-m-d H:i:s'); return $data; } protected function beforeUpdate(array $data){ $data = $this->passwordHash($data); $data['data']['updated_at'] = date('Y-m-d H:i:s'); return $data; } protected function passwordHash(array $data){ if(isset($data['data']['password'])) $data['data']['password'] = password_hash($data['data']['password'], PASSWORD_DEFAULT); return $data; } } ?> |
Create Custom Validation rules
Here, we create the custom validation rules to check the user is valid or not. so you can follow the below example.
app/Validation/UserRules.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <?php namespace App\Validation; use App\Models\UserModel; class UserRules { public function validateUser(string $str, string $fields, array $data){ $model = new UserModel(); $user = $model->where('email', $data['email']) ->first(); if(!$user) return false; return password_verify($data['password'], $user['password']); } } ?> |
app/Config/Validation.php
now, we have to add that file. The edit app/Config/Validation.php and add the new file to the $rule Set array.
1 2 3 4 | public $ruleSets = [ .... \App\Validation\UserRules::class, ]; |
Creating a Filter
The filter handles the request before or after the controllers execute. so we are using it to check user authentication.
app/Filters/Auth.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <?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) { // Do something here if(! session()->get('isLoggedIn')){ return redirect()->to('/'); } } //-------------------------------------------------------------------- public function after(RequestInterface $request, ResponseInterface $response) { // Do something here } } ?> |
app/Filters/Noauth.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <?php namespace App\Filters; use CodeIgniter\HTTP\RequestInterface; use CodeIgniter\HTTP\ResponseInterface; use CodeIgniter\Filters\FilterInterface; class Noauth implements FilterInterface { public function before(RequestInterface $request) { // Do something here if(session()->get('isLoggedIn')){ return redirect()->to('/dashboard'); } } //-------------------------------------------------------------------- public function after(RequestInterface $request, ResponseInterface $response) { // Do something here } } ?> |
app/Filters/UsersCheck.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | <?php namespace App\Filters; use CodeIgniter\HTTP\RequestInterface; use CodeIgniter\HTTP\ResponseInterface; use CodeIgniter\Filters\FilterInterface; class UsersCheck implements FilterInterface { public function before(RequestInterface $request) { // Do something here // If segment 1 == login //we have to redirect the request to the second segment $uri = service('uri'); if($uri->getSegment(1) == 'login'){ if($uri->getSegment(2) == '') $segment = '/'; else $segment = '/'.$uri->getSegment(2); return redirect()->to($segment); } } //-------------------------------------------------------------------- public function after(RequestInterface $request, ResponseInterface $response) { // Do something here } } ?> |
app/config/Filters.php
Once you have created your filters then we need to configure them in app/Config/Filters.php.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | <?php namespace Config; use CodeIgniter\Config\BaseConfig; class Filters extends BaseConfig { // Makes reading things below nicer, // and simpler to change out script that's used. public $aliases = [ 'csrf' => \CodeIgniter\Filters\CSRF::class, 'toolbar' => \CodeIgniter\Filters\DebugToolbar::class, 'honeypot' => \CodeIgniter\Filters\Honeypot::class, 'auth' => \App\Filters\Auth::class, 'noauth' => \App\Filters\Noauth::class, 'userscheck' => \App\Filters\UsersCheck::class, ]; // Always applied before every request public $globals = [ 'before' => [ 'userscheck' //'honeypot' // 'csrf', ], 'after' => [ 'toolbar', //'honeypot' ], ]; // Works on all of a particular HTTP method // (GET, POST, etc) as BEFORE filters only // like: 'post' => ['CSRF', 'throttle'], public $methods = []; // List filter aliases and any before/after uri patterns // that they should run on, like: // 'isLoggedIn' => ['before' => ['account/*', 'profiles/*']], public $filters = []; } ?> |
Define The Route
Add the following route code in the “app/config/Routes.php” file.
1 2 3 4 5 6 7 8 9 10 11 12 | $routes->setDefaultNamespace('App\Controllers'); $routes->setDefaultController('Login'); $routes->setDefaultMethod('index'); $routes->setTranslateURIDashes(false); $routes->set404Override(); $routes->setAutoRoute(true); $routes->get('/', 'Login::index', ['filter' => 'noauth']); $routes->get('logout', 'Login::logout'); $routes->match(['get','post'],'register', 'Login::register', ['filter' => 'noauth']); $routes->get('dashboard', 'Dashboard::index',['filter' => 'auth']); |
Create view Files
here in this step, we need to create a new default.php, login.php, register.php, and dashboard.php files into the views directory. for that, you can see the below example.
app/views/layouts/default.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | <!DOCTYPE html> <html lang="en" dir="ltr"> <head> <meta charset="utf-8"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> <link rel="stylesheet" href="/assets/css/style.css"> <title></title> </head> <body> <?php $uri = service('uri'); ?> <nav class="navbar navbar-expand-lg navbar-dark bg-dark"> <div class="container"> <a class="navbar-brand" href="/">Ci4 Login</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarSupportedContent"> <?php if (session()->get('isLoggedIn')): ?> <ul class="navbar-nav mr-auto"> <li class="nav-item <?= ($uri->getSegment(1) == 'dashboard' ? 'active' : null) ?>"> <a class="nav-link" href="/dashboard">Dashboard</a> </li> </ul> <ul class="navbar-nav my-2 my-lg-0"> <li class="nav-item"> <a class="nav-link" href="/logout">Logout</a> </li> </ul> <?php else: ?> <ul class="navbar-nav mr-auto"> <li class="nav-item <?= ($uri->getSegment(1) == '' ? 'active' : null) ?>"> <a class="nav-link" href="/">Login</a> </li> <li class="nav-item <?= ($uri->getSegment(1) == 'register' ? 'active' : null) ?>"> <a class="nav-link" href="/register">Register</a> </li> </ul> <?php endif; ?> </div> </div> </nav> <?= $this->renderSection('content') ?> <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script> </body> </html> |
app/views/login.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | <?= $this->extend('layouts\default') ?> <?= $this->section('content') ?> <div class="container"> <div class="row"> <div class="col-12 col-sm-8 offset-sm-2 col-md-6 offset-md-3 mt-5 pt-3 pb-3 bg-white from-wrapper"> <div class="container"> <h3>Login</h3> <hr> <?php if (session()->get('success')): ?> <div class="alert alert-success" role="alert"> <?= session()->get('success') ?> </div> <?php endif; ?> <form class="" action="/" method="post"> <div class="form-group"> <label for="email">Email address</label> <input type="text" class="form-control" name="email" id="email" value="<?= set_value('email') ?>"> </div> <div class="form-group"> <label for="password">Password</label> <input type="password" class="form-control" name="password" id="password" value=""> </div> <?php if (isset($validation)): ?> <div class="col-12"> <div class="alert alert-danger" role="alert"> <?= $validation->listErrors() ?> </div> </div> <?php endif; ?> <div class="row"> <div class="col-12 col-sm-4"> <button type="submit" class="btn btn-primary">Login</button> </div> <div class="col-12 col-sm-8 text-right"> <a href="/register">Don't have an account yet?</a> </div> </div> </form> </div> </div> </div> </div> <?= $this->endSection() ?> |
app/views/register.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | <?= $this->extend('layouts\default') ?> <?= $this->section('content') ?> <div class="container"> <div class="row"> <div class="col-12 col-sm-8 offset-sm-2 col-md-6 offset-md-3 mt-5 pt-3 pb-3 bg-white from-wrapper"> <div class="container"> <h3>Register</h3> <hr> <form class="" action="/register" method="post"> <div class="row"> <div class="col-12 col-sm-6"> <div class="form-group"> <label for="firstname">First Name</label> <input type="text" class="form-control" name="firstname" id="firstname" value="<?= set_value('firstname') ?>"> </div> </div> <div class="col-12 col-sm-6"> <div class="form-group"> <label for="lastname">Last Name</label> <input type="text" class="form-control" name="lastname" id="lastname" value="<?= set_value('lastname') ?>"> </div> </div> <div class="col-12"> <div class="form-group"> <label for="email">Email address</label> <input type="text" class="form-control" name="email" id="email" value="<?= set_value('email') ?>"> </div> </div> <div class="col-12 col-sm-6"> <div class="form-group"> <label for="password">Password</label> <input type="password" class="form-control" name="password" id="password" value=""> </div> </div> <div class="col-12 col-sm-6"> <div class="form-group"> <label for="password_confirm">Confirm Password</label> <input type="password" class="form-control" name="password_confirm" id="password_confirm" value=""> </div> </div> <?php if (isset($validation)): ?> <div class="col-12"> <div class="alert alert-danger" role="alert"> <?= $validation->listErrors() ?> </div> </div> <?php endif; ?> </div> <div class="row"> <div class="col-12 col-sm-4"> <button type="submit" class="btn btn-primary">Register</button> </div> <div class="col-12 col-sm-8 text-right"> <a href="/">Already have an account</a> </div> </div> </form> </div> </div> </div> </div> <?= $this->endSection() ?> |
app/views/dashboard.php
1 2 3 4 5 6 7 8 9 10 | <?= $this->extend('layouts\default') ?> <?= $this->section('content') ?> <div class="container"> <div class="row"> <div class="col-12"> <h1>Hello, <?= session()->get('firstname') ?></h1> </div> </div> </div> <?= $this->endSection() ?> |
Run Our Application
We can start the server and run this example using the below command.
1 | php spark serve |
Now we will run our example using the below Url in the browser.
1 | http://localhost:8080/ |