A web application built without frameworks that demonstrates authentication, authorization, and role-based permissions using pure PHP.
✅ Authentication System
- Login/Logout functionality
- Session-based authentication
- Bcrypt password hashing
- Database-backed session storage
✅ Authorization & Permissions
- Role-based access control (RBAC)
- Three roles: Admin, User, Guest
- Permission checks throughout the application
- Middleware-style route protection
✅ Database Integration
- PostgreSQL database
- User, Role, and Session management
- Migration scripts included
✅ API Endpoints
- Public API (no authentication required)
- Authenticated user API
- Admin-only API endpoints
- JSON responses
✅ No Frameworks
- Pure PHP implementation
- Custom routing system
- MVC-inspired architecture
- PSR-4 autoloading
- PHP: 8.4
- Database: PostgreSQL 16
- Web Server: Nginx
- Environment: Docker + Docker Compose
- Password Hashing: bcrypt
- Session Storage: Database
webAppPermissions/
├── .cursor/memory-bank/ # Project documentation
├── docker/ # Docker configuration
├── public/ # Web-accessible files
│ ├── index.php # Application entry point
│ └── style.css # Styles
├── src/
│ ├── Auth/ # Authentication & authorization
│ │ ├── Auth.php
│ │ └── Middleware.php
│ ├── Config/ # Configuration classes
│ │ ├── App.php
│ │ └── Database.php
│ ├── Controllers/ # Request handlers
│ │ ├── ApiController.php
│ │ ├── AuthController.php
│ │ ├── DashboardController.php
│ │ └── HomeController.php
│ ├── Database/ # Database connection
│ │ └── Connection.php
│ ├── Models/ # Data models
│ │ ├── Model.php
│ │ ├── Role.php
│ │ ├── Session.php
│ │ └── User.php
│ ├── Views/ # HTML templates
│ │ ├── layout.php
│ │ ├── login.php
│ │ ├── dashboard.php
│ │ ├── admin.php
│ │ ├── 403.php
│ │ └── 404.php
│ └── Router.php # Custom routing
├── .env.example # Environment variables template
├── composer.json # Composer configuration
└── docker-compose.yml # Docker services
- Docker and Docker Compose
- Git
-
Clone the repository (or you already have it)
-
Copy environment file
cp .env.example .env
Adjust the values in
.envif needed (defaults should work). -
Start Docker containers
docker compose up -d
-
Install dependencies (if not already installed)
docker compose exec php-fpm composer install -
Initialize the database
The database will be automatically initialized when the PostgreSQL container starts for the first time. It will:
- Create all necessary tables
- Seed roles (admin, user, guest)
- Create test users
-
Access the application
Open your browser and navigate to:
http://localhost
The following test accounts are automatically created:
| Role | Username | Password | Description |
|---|---|---|---|
| Admin | admin |
admin123 |
Full system access |
| User | user |
user123 |
Standard user access |
| Guest | guest |
guest123 |
Limited access |
GET /api/infoReturns general information about the application.
Example:
curl http://localhost/api/infoGET /api/meReturns the currently authenticated user's information.
Example:
curl -H "Cookie: webapp_session=YOUR_SESSION_TOKEN" http://localhost/api/meGET /api/usersReturns a list of all users (admin only).
GET /api/statsReturns user and role statistics (admin only).
| Method | Path | Description | Auth Required | Role Required |
|---|---|---|---|---|
| GET | / |
Home page (redirects) | No | - |
| GET | /login |
Login form | No | - |
| POST | /login |
Process login | No | - |
| POST | /logout |
Logout user | Yes | - |
| GET | /dashboard |
User dashboard | Yes | - |
| GET | /403 |
Forbidden page | No | - |
| GET | /404 |
Not found page | No | - |
- User submits username/password via login form
- System verifies credentials against database
- Password is checked using
password_verify()with bcrypt - On success, creates session token (32-byte random)
- Session stored in database with expiration time
- Token sent to user via cookie
- Subsequent requests include cookie for authentication
- Session validated and refreshed on each request
- Middleware checks if user is authenticated
- User role is retrieved from database
- Permissions checked against role
- Access granted or denied (403 Forbidden)
- roles: Role definitions (admin, user, guest)
- users: User accounts with role assignment
- sessions: Active user sessions
- permissions: Role-based permissions
- Each user has exactly one role
- Each session belongs to one user
- Permissions are assigned to roles
docker compose exec php-fpm composer dump-autoloaddocker compose exec postgres psql -U permissions -d webApp# PHP-FPM logs
docker compose logs -f php-fpm
# Nginx logs
docker compose logs -f webserver
# PostgreSQL logs
docker compose logs -f postgresdocker compose down# Stop containers
docker compose down -v
# Start containers (database will be re-initialized)
docker compose up -d- Password Hashing: bcrypt with automatic salt
- SQL Injection Prevention: PDO prepared statements
- XSS Prevention: Output escaping with
htmlspecialchars() - Session Security:
- Random token generation
- Database storage
- Expiration handling
- HTTP-only cookies
- SameSite cookie attribute
This project uses PHP-CS-Fixer for code style consistency.
# Check and fix code style
composer lintThis is a demonstration project for educational purposes.
Ivelin Ivanov (ivelin.ivanov4@gmail.com)
Built without frameworks - Pure PHP implementation demonstrating fundamental web development concepts.