Introduction
This tutorial is about CodeIgniter 4 MySQL Login Logout example with MySQL database version 8. I will use CodeIgniter’s session library to store logged in user’s data. The session data get destroyed as soon as user logs out of the application.
I am also going to create a custom config to use a key or variable across the application. I will use this key or variable to store the flash data. Flash data is part of the session data, but it only keeps the data available for the next request. So, if you store data in Nth request then your data will be available up to N+1 request.
I am going to create a library called AuthLibrary that will contain the common functionalities for performing authentication checks across the application.
I am also showing how to work with language support in CodeIgniter 4 application, though I have used only English language for this application.
You will also see how to allow a user access private area of the application once user logs into the application. I will use CodeIgniter’s form validation library to validate the input fields.
Related Posts:
Prerequisites
PHP 7.4.23, CodeIgniter 4.1.4, MySQL Server 8.0.26
Project Directory
It’s assumed that you have setup PHP and CodeIgniter in your system.
Now I will create a project root directory called codeigniter-login-logout.
Now move all the directories and files from CodeIgniter framework into the project root directory.
I may not mention the project root directory in subsequent sections, and I will assume that I am talking with respect to the project root directory.
MySQL table
I have created the following table to store user login details. If you are using MySQL version less than 8 then you need to specify the size of the column value for int data type.
CREATE TABLE login (
id INT unsigned COLLATE utf8mb4_unicode_ci AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(255) COLLATE utf8mb4_unicode_ci NOT NULL,
password VARCHAR(255) COLLATE utf8mb4_unicode_ci NOT NULL,
last_login DATETIME COLLATE utf8mb4_unicode_ci DEFAULT CURRENT_TIMESTAMP
);
For testing purpose, I have stored one user’s login information into the table. Make sure you use strong encryption mechanism for storing password in the database table.
insert into login(username,password) values ('user','user');
Database Configuration
You need to setup database connection in order to fetch or write data to the table. The following configuration is done in the file app/Config/Database.php under the default group of database setting. Make sure you change or update the configuration according to yours. You can also setup your database using the .env file.
The main properties I have shown below, and you can change according to your values:
...
'username' => 'root',
'password' => 'root',
'database' => 'roytuts',
...
'charset' => 'utf8mb4',
'DBCollat' => 'utf8mb4_unicode_ci',
...
Model Class
The model class is responsible for interacting with database and performing required activities as requested by clients.
The following code is written into the file app/Models/AuthModel.php file:
<?php
namespace App\Models;
use CodeIgniter\Model;
class AuthModel extends Model {
protected $login = 'login';
function get_login_details($username, $password) {
$query = $this->db->table($this->login)->where(['username' => $username, 'password' => $password])->limit(1)->get();
return $query->getRow();
}
}
The above class has get_login_details() function that fetches the required details for a given user.
Authentication Library
I have created a library file called AuthLibrary.php having common functionalities such as, login()
, logout()
, is_logged_in()
, etc. to perform authentication check across the application.
The following code is written into the file app/Libraries/AuthLibrary.php file:
<?php
namespace App\Libraries;
use App\Models\AuthModel;
/**
* Description of Auth Library
*
* @author https://roytuts.com
*/
class AuthLibrary {
private $db;
private $msg;
private $request;
public function __construct() {
$this->db = \Config\Database::connect();
$this->request = \Config\Services::request();
}
private function set_msg($msg) {
$this->msg .= $msg . nl2br("\n");
}
function get_msg() {
return $this->msg;
}
function login($username, $password) {
if ((strlen($username) > 0) AND (strlen($password) > 0)) {
$model = new AuthModel();
$login = $model->get_login_details($username, $password);
if ($login !== NULL) {
$session = session();
$session->set(array(
'user_name' => $login->username,
'last_login' => $login->last_login
));
return TRUE;
} else { // fail - wrong creadentials
$this->set_msg(lang('Message.incorrect_credentials'));
}
}
return FALSE;
}
function logout() {
$session = session();
$session->set(array('user_name' => '', 'last_login' => ''));
$session->destroy();
}
function is_logged_in() {
$session = session();
return $session->has('user_name');
}
}
Controller Class
The controller class is the entry point for the web application and a controller class handles request and response coming from and going back to clients.
The controller class performs the business logic for the application. The controller class is also responsible for validating, sanitizing, filtering the malformed request data before the data can be processed further for the application requirements.
The code for controller class is written into a file app/Controllers/Auth.php.
<?php
namespace App\Controllers;
use App\Libraries\AuthLibrary;
class Auth extends BaseController {
private $msg;
private $authLib;
public function __construct() {
$this->authLib = new AuthLibrary();
}
private function display_msg($msg) {
$this->msg .= $msg . nl2br("\n");
}
function index() {
if (!$this->authLib->is_logged_in()) {
return redirect()->to(site_url('auth/login'));
} else {
echo view('home');
}
}
function login() {
$session = session();
if ($this->request->getPost('login')) {
$validation = \Config\Services::validation();
$validation->setRules([
'username' => ['label' => 'Username', 'rules' => 'trim|required|max_length[100]'],
'password' => ['label' => 'Password', 'rules' => 'trim|required|max_length[25]']
]);
if (!$validation->withRequest($this->request)->run()) {
//Error
echo view('login', ['errors' => $validation->getErrors()]);
} else {
$username = $this->request->getPost('username');
$password = $this->request->getPost('password');
if ($this->authLib->login($username, $password)) {
//Success
$config = new \Config\CustomConfig();
$key = $config->msgKey;
$session->setFlashdata($key, lang('Message.login_success'));
$session->keepFlashdata($key);
return redirect()->to(site_url());
} else {
$errors = $this->authlib->get_msg();
$this->display_msg($errors);
echo view('login', ['errors' => $this->msg]);
}
}
} else {
$config = new \Config\CustomConfig();
$key = $config->msgKey;
echo view('login', ['msg' => $session->getFlashdata($key)]);
}
}
function logout() {
if ($this->authLib->is_logged_in()) {
$this->authLib->logout();
}
return redirect()->to(site_url());
}
}
In the above controller class, the index()
function checks whether a user already logged in or not and if not, then redirects to the login page.
You can also use filters to check whether a user is logged in or not.
In the login()
function the input fields are captured and passed to the AuthLibrary to validate the user against database values and if user found then put into the session.
The login welcome message is stored into flash data which is shown on the home page of the user’s dashboard for the first time until user refreshes the page dashboard.
The logout()
function logs user out of the application and destroys the session.
Custom Config
I have created a custom config (app/Config/CustomConfig.php) that will be used for the application. This variable or key mainly used for storing flashdata in a session.
<?php
namespace Config;
use CodeIgniter\Config\BaseConfig;
class CustomConfig extends BaseConfig {
public $msgKey = 'msg_key';
}
Views
The view files which will display the data or UI (User Interface) to the end users. The app/Views/login.php displays login page where user inputs credentials to gain access to the private area.
The app/Views/home.php file which displays the private area belongs to a particular user onvce he/she is successfully logged in.
View – login.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Welcome to CodeIgniter 4 Login Logout Example</title>
<meta name="description" content="The small framework with powerful features">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" type="image/png" href="/favicon.ico"/>
<link rel="stylesheet" href="/css/login.css"/>
</head>
<body>
<div class="wrap">
<div id="content">
<div id="main">
<div class="full_w">
<?php
if (isset($msg) && !empty($msg)) {
echo '<div class="n_ok"><p>';
if(is_array($msg)) {
foreach ($msg as $m) :
echo esc($m);
endforeach;
} else {
echo $msg;
}
echo '</p></div>';
}
?>
<?php
helper('form');
echo form_open(current_url(true));
if (isset($errors) && !empty($errors)) {
echo '<div class="n_error">';
foreach ($errors as $error) :
echo esc($error);
endforeach;
echo '</div><div class="sep"></div>';
}
?>
<label for="username">Username:</label>
<input id="username" name="username" class="text" type="text"
maxlength="100"/>
<label for="password">Password:</label>
<input id="password" name="password" type="password"
class="text" maxlength="25"/>
<div class="sep"></div>
<input type="submit" name="login" id="login" value="Login"/>
<?php
echo form_close();
?>
</div>
</div>
</div>
</div>
</body>
</html>
You need to load helper(‘form’)
if you want to use CodeIgniter’s form_open()
function. The current_url(true)
function is used for the action part of the form. This uses basically the current URI string of the application.
The login.css file is used for applying basic style to the login page and this css file is placed under public/css folder in CodeIgniter 4 framework.
View – home.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Welcome to CodeIgniter 4 Login Logout Example</title>
<meta name="description" content="The small framework with powerful features">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" type="image/png" href="/favicon.ico"/>
</head>
<body>
<div id="container">
<div id="body">
<p>
<?php
$session = session();
$config = new \Config\CustomConfig();
$key = $config->msgKey;
if($session->getFlashdata($key)) {
echo $session->getFlashdata($key);
}
?>
</p>
<p>Welcome to Dashboard</p>
<p>
Last login: <strong><?php echo $session->get('last_login') == NULL ? 'First Time' : $session->get('last_login'); ?></strong>
Welcome,</span> <strong><?php echo $session->get('user_name'); ?></strong>
<?php echo anchor('auth/logout', '[ Logout ]', 'title="Logout"'); ?>
</p>
</div>
</div>
</body>
</html>
In the above file, the welcome message is displayed from the flashdata if found. The last login date & time and user name are displayed from the session data. The Logout link is created using the anchor()
function in CodeIgniter 4 framework.
Hope this tutorial helped you to understand and to implement basic login and logout functionalities in CodeIgniter 4.
Language Support
I have created a file app/Language/en/Message.php file to put the following content:
<?php
return [
'incorrect_credentials' => 'Incorrect username or password',
'login_success' => 'You have been successfully logged in',
'logout_success' => 'You have been successfully logged out'
];
This will help you to put the similar messages in different languages.
Route Configuration
You also need to configure route to point to your own controller file instead of the default controller that comes with the framework.
Search for the line $routes->setDefaultController('Home');
and replace it by $routes->setDefaultController('Auth');
.
Search for the line $routes->get('/', 'Home::index');
and replace it by your controller name, for this example, $routes->get('/', 'Auth::index');
.
These route configurations are done on the file app/Config/Routes.php.
Deploying the Application
I am not going to use any external server but CLI command to run the application. Make sure you start the MySQL database server before you start your application. If you want to use external server to run your application, you can use, for example, Apache HTTP Server. Execute the following command on your project root directory to run your application.
php spark serve
Your application will be running on localhost and port 8080.
Testing CodeIgniter Login Logout
When you hit the UTR http://localhost:8080 in the browser, you will be redirected to the following login page:
If you try to submit the login page without entering credentials then you will get the validation error:
Once you login using credentials (user/user), then you will be redirected to the dashboard:
If you refresh the dashboard page then your flash message gets disappeared.
If you click on Logout link then you will be redirected to the login page again.