PHP web application implementing a secure authentication system with bcrypt password hashing and email-based password recovery.
- Secure login with bcrypt password hashing (
password_hash()/password_verify()) - Password recovery via email with expiring single-use tokens
- Admin user management (create, edit, delete)
- SweetAlert2 toast notifications for all CRUD and authentication actions
- SweetAlert2 confirmation dialog for user deletion in
/users - Front controller architecture with clean URL routing
- OOP controllers (
AuthController,UserController) with thin delegator pattern - OOP model layer with MySQLi prepared statements
- Shared view helpers (
renderView,renderProtectedView) for consistent template rendering - PHPMailer integration for transactional email (STARTTLS)
- Consistent color palette via CSS variables (
--color-dark,--color-accent) - File-based cache for admin user listing with automatic invalidation on create/edit/delete
- Graceful cache fallback: if
storage/cacheis not writable, the app continues without cache and logs a warning
- PHP >= 8.2
- MySQL / MariaDB
- Apache (XAMPP recommended)
- Gmail account with an App Password (or any SMTP provider)
- Clone the repository:
git clone https://github.com/Jandres25/Encriptacion_PHP.git
cd Encriptacion_PHP- Copy and configure the environment file:
cp .env.example .envEdit .env with your credentials:
DB_HOST=localhost
DB_USERNAME=root
DB_PASSWORD=
DB_DATABASE=login
SMTP_HOST=smtp.gmail.com
SMTP_USERNAME=your@gmail.com
SMTP_PASSWORD=your_app_password
SMTP_PORT=587
APP_URL=http://localhost/Encriptacion_PHP
APP_TIMEZONE=America/Bogota
CACHE_ENABLED=true
CACHE_TTL_USERS=60
CACHE_TTL_USERS defines (in seconds) how long the /users list stays cached.
The storage/cache directory must be writable by your web server user.
- Import the database schema:
mysql -u root -p < database/schema.sql- (Optional) Load sample data:
mysql -u root -p < database/seeds.sql- Place the project in your server's web root (e.g.
htdocs/in XAMPP) and openAPP_URLin your browser.
├── app/
│ ├── Config/
│ │ ├── autoload.php # Bootstrap entry point
│ │ ├── cache.php # Cache bootstrap + appCache() helper
│ │ ├── config.php # Loads .env, defines APP_URL
│ │ ├── database.php # MySQLi connection ($connection)
│ │ └── view_helpers.php # renderView() / renderProtectedView()
│ ├── Controller/
│ │ ├── auth/
│ │ │ ├── AuthController.php # App\Controller\Auth\AuthController — all auth logic
│ │ │ ├── login.php # Thin delegator → AuthController::login()
│ │ │ ├── logout.php # Thin delegator → AuthController::logout()
│ │ │ ├── reset.php # Thin delegator → AuthController::forgotPassword()
│ │ │ └── update_password.php # Thin delegator → AuthController::resetPassword()
│ │ ├── user/
│ │ │ ├── UserController.php # App\Controller\User\UserController — all user CRUD logic
│ │ │ ├── index.php # Thin delegator → UserController::index()
│ │ │ ├── create.php # Thin delegator → UserController::create()
│ │ │ ├── edit.php # Thin delegator → UserController::edit()
│ │ │ └── delete.php # Thin delegator → UserController::delete()
│ │ └── home.php # Dashboard controller
│ └── Model/
│ └── User.php # App\Model\User — OOP model with prepared statements
├── database/
│ ├── schema.sql # Table definitions (users + password_resets)
│ └── seeds.sql # Sample data
├── libs/
│ ├── Cache/ # File-based cache implementation
│ └── PHPMailer/ # PHPMailer (no Composer)
├── public/
│ ├── css/ # Bootstrap, all.min.css (FontAwesome), estilo.css, layout-protected.css
│ ├── DataTables/ # DataTables combined bundle (datatables.js)
│ ├── img/ # Images and icons
│ ├── js/ # jQuery, Bootstrap JS, Popper, sweetalert2.all.min.js, users-table.js, users-delete.js
│ ├── webfonts/ # FontAwesome webfonts (used by all.min.css)
│ ├── .htaccess # Apache rewrite rules for clean URLs
│ └── index.php # Front controller — routes by path (/login, /users, ...)
├── storage/
│ └── cache/ # Runtime cache files (*.cache)
├── views/
│ ├── auth/ # login, forgot_password, reset_password
│ ├── layouts/ # shared header/footer and messages.php for notifications
│ ├── user/ # index, create, edit
│ ├── home/ # home/index.php
│ │ └── index.php # Dashboard view
├── .env.example # Environment variable template
└── database/schema.sql # Source of truth for DB schema
- Open
http://localhost/Encriptacion_PHP/in your browser - Log in with a seeded user (e.g. username
Admin, password123456) - Admin users (
is_admin = 1) see the Users link in the nav → full CRUD - To recover a password, click "Forgot your password?" on the login page
The app uses a single front controller (public/index.php) with clean URL paths:
| URL | Page |
|---|---|
/ |
Dashboard |
/login |
Login |
/forgot-password |
Forgot password |
/reset-password?token=... |
Reset password |
/users |
User list (admin only) |
/users/create |
Create user |
/users/edit?id=X |
Edit user |
/users/delete?id=X |
Delete user |
- Passwords hashed with bcrypt (
PASSWORD_DEFAULT) - Session set only after successful
password_verify() - Reset tokens: 256-bit, 1-hour expiry, single-use
- All DB queries via MySQLi prepared statements
- Email validated with
filter_var()before DB lookup - SMTP with STARTTLS (port 587)
- Cached endpoint:
/usersuser listing (App\Model\User::getAll()) - Cache key: fixed key (
users.all), so requests rewrite the same cache file instead of creating unlimited files - Invalidation: cache is cleared after create, edit, delete, and password update operations
- Controls:
CACHE_ENABLED=true|falseCACHE_TTL_USERS=<seconds>(e.g.,600for 10 minutes)
- Storage:
storage/cache/*.cache - If the directory is not writable, the app disables cache for the request and logs a warning (no HTTP 500)
- Open Firefox DevTools (
F12) → Red tab. - Open
/usersand note the request Duración. - Reload several times within TTL: the first request is usually slower; the next ones should be faster.
- Set
CACHE_ENABLED=false, reload again, and compare durations.
- Protected pages use
renderProtectedView()fromapp/Config/view_helpers.php. - Shared protected layout lives in
views/layouts/header.phpandviews/layouts/footer.php. - DataTables initialization for the users table was moved to
public/js/users-table.js. - User deletion confirmation in
views/user/index.phpis handled bypublic/js/users-delete.js(SweetAlert2). - Full-height protected layout behavior is in
public/css/layout-protected.css.
- Fork the project
- Create a feature branch (
git checkout -b feature/my-feature) - Commit your changes (
git commit -m 'Add my feature') - Push to the branch (
git push origin feature/my-feature) - Open a Pull Request
This project is licensed under the MIT License — see the LICENSE file for details.
Jandres25 - jandrespb4@gmail.com
Project link: https://github.com/Jandres25/Encriptacion_PHP