Authentication
Overview
Yabasi framework provides flexible authentication mechanisms that support both session-based and token-based authentication. The authentication system is designed to be secure, scalable, and easy to implement while following modern security practices.
Secure by Default
Built-in protection against common vulnerabilities including CSRF, XSS, and session hijacking.
Flexible Integration
Supports multiple authentication guards and custom authentication providers.
Performance Optimized
Efficient session handling and caching mechanisms for optimal performance.
Session vs Token Authentication
Session-based Authentication
- Maintains user state on the server using PHP sessions
- Ideal for traditional web applications
- Built-in CSRF protection
- Automatic session security features
Session-based authentication is enabled by default in web routes.
Token-based Authentication
- Stateless authentication using JWT or API tokens
- Perfect for APIs and mobile applications
- Scalable across multiple servers
- Support for token expiration and refresh
Token authentication is automatically enabled for API routes.
Authentication Flow
-
User Credentials Submission
Application receives login credentials via form submission or API request.
-
Validation
Credentials are validated against security rules and database records.
-
Authentication Process
Yabasi verifies credentials and creates appropriate authentication session or token.
-
Session/Token Management
Framework maintains authentication state and handles session/token lifecycle.
Security Considerations
Common Vulnerabilities
- Session fixation
- Cross-site scripting (XSS)
- CSRF attacks
- Man-in-the-middle attacks
Built-in Protections
- Automatic CSRF token validation
- Secure session handling
- Password hashing
- SSL/TLS support
Configuration
Yabasi's authentication system requires minimal configuration to get started. The main components include the auth configuration file, user model setup, and database structure.
Auth Config Structure
Authentication configuration is defined in your config/config.php
file under the auth
key:
return [
'auth' => [
'model' => Yabasi\Models\User::class,
'table' => 'users',
'username_field' => 'email',
'password_field' => 'password',
'session_lifetime' => 120, // minutes
'token_lifetime' => 60, // minutes
'password_timeout' => 10800 // seconds
],
];
Option | Description | Default |
---|---|---|
model | The user model class | Yabasi\Models\User::class |
table | Database table for users | users |
username_field | Field used for authentication |
User Model Setup
Your User model should extend the base Model class and implement the AuthenticatableInterface:
namespace App\Models;
use Yabasi\Database\Model;
use Yabasi\Auth\AuthenticatableInterface;
class User extends Model implements AuthenticatableInterface
{
protected static string $table = 'users';
protected array $fillable = [
'name',
'email',
'password',
];
protected array $hidden = [
'password',
'remember_token',
];
}
Required Methods
getAuthIdentifier()
- Returns the unique identifier for authenticationgetAuthPassword()
- Returns the hashed password fieldgetRememberToken()
- Returns the remember me token
Database Requirements
Your users table must include these minimum required fields:
public function up(): void
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
Make sure to always hash passwords before storing them in the database. Yabasi provides built-in methods for secure password hashing.
Basic Usage
Learn how to implement common authentication operations in Yabasi. This section covers all the basic functionality you'll need for a secure authentication system.
User Registration
To register a new user, you'll need to validate the input data and create a new user record:
use Yabasi\Http\Request;
use Yabasi\Models\User;
use Yabasi\Auth\Auth;
class AuthController extends Controller
{
public function register(Request $request)
{
$validated = $request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users',
'password' => 'required|min:8'
]);
$user = User::create([
'name' => $validated['name'],
'email' => $validated['email'],
'password' => Auth::hash($validated['password'])
]);
Auth::login($user);
return $this->response->redirect('/dashboard');
}
}
Registration Form Example
<form method="POST" action="/register"> {{ csrf_field() }} <div class="mb-4"> <label for="name">Name</label> <input type="text" name="name" id="name" required> </div> <div class="mb-4"> <label for="email">Email</label> <input type="email" name="email" id="email" required> </div> <div class="mb-4"> <label for="password">Password</label> <input type="password" name="password" id="password" required> </div> <button type="submit">Register</button> </form>
Login Implementation
Implement user login with email/password credentials:
public function login(Request $request)
{
$credentials = $request->validate([
'email' => 'required|email',
'password' => 'required'
]);
if (Auth::attempt($credentials)) {
$request->session()->regenerate();
return $this->response->redirect('/dashboard');
}
return $this->response->back()->with('error', 'Invalid credentials');
}
Available Login Methods
Auth::attempt($credentials)
- Attempt to authenticate a userAuth::login($user)
- Log in a user instanceAuth::loginById($id)
- Log in a user by ID
Logout Process
Implementing logout functionality:
public function logout(Request $request)
{
Auth::logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return $this->response->redirect('/login');
}
Password Management
// Hash a password
$hashedPassword = Auth::hash($password);
// Verify a password
if (Auth::verify($password, $user->password)) {
// Password is correct
}
Password Reset
// Generate password reset token
$token = Auth::createPasswordResetToken($user);
// Reset password
Auth::resetPassword($token, $newPassword);
Session Handling
// Generate password reset token
$token = Auth::createPasswordResetToken($user);
// Reset password
Auth::resetPassword($token, $newPassword);
Yabasi automatically handles session security including CSRF protection, session fixation prevention, and secure cookie settings.
Authentication Best Practices
- Always validate user input before processing
- Regenerate session ID after login and logout
- Use HTTPS in production environments
- Implement rate limiting for login attempts
Guards
Guards in Yabasi determine how users are authenticated for each request. Multiple guards can be used to provide different types of authentication for different parts of your application.
Available Guards
Session Guard
Default guard for web applications using PHP sessions.
// Using session guard Auth::guard('web')->attempt($credentials);
Token Guard
For API authentication using tokens.
// Using token guard Auth::guard('api')->authenticate($token);
'auth' => [
'defaults' => [
'guard' => 'web',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
'lifetime' => 60, // minutes
],
],
]
Custom Guard Implementation
Create a custom guard by implementing the GuardInterface:
namespace App\Auth;
use Yabasi\Auth\Guards\GuardInterface;
class CustomGuard implements GuardInterface
{
protected $user;
public function check(): bool
{
return $this->user !== null;
}
public function user()
{
return $this->user;
}
public function validate(array $credentials = []): bool
{
// Custom validation logic
}
public function setUser($user): void
{
$this->user = $user;
}
}
Register Custom Guard
// In your service provider
use Yabasi\Auth\Auth;
public function boot()
{
Auth::extend('custom', function ($app, $name, array $config) {
return new CustomGuard($app['request']);
});
}
Multiple Authentication
Using Multiple Guards
// Check authentication with specific guard if (Auth::guard('api')->check()) { // User is authenticated with API guard } // Get user from specific guard $user = Auth::guard('web')->user(); // Attempt authentication with specific guard Auth::guard('web')->attempt($credentials);
Note that each guard maintains its own authentication state. A user authenticated with one guard may not be authenticated with another.
// Routes with different guards
$router->group(['guard' => 'web'], function ($router) {
$router->get('/dashboard', 'DashboardController@index');
});
$router->group(['guard' => 'api'], function ($router) {
$router->get('/api/user', 'ApiController@user');
});
Guard-Specific Middleware
// Protect routes with specific guard $router->middleware(['auth:api'])->group(function ($router) { // Routes protected by API guard }); $router->middleware(['auth:web'])->group(function ($router) { // Routes protected by web guard });
Guard Best Practices
- Use the appropriate guard for your authentication context
- Implement proper error handling for guard failures
- Consider rate limiting for token-based authentication
- Keep guard configurations secure and environment-specific
Middleware
Authentication middleware in Yabasi provides a secure way to protect your routes and ensure users are properly authenticated before accessing specific parts of your application.
Auth Middleware Usage
Basic Usage
// Single Route Protection
$router->get('/dashboard', 'DashboardController@index')
->middleware('auth');
// Group Route Protection
$router->group(['middleware' => ['auth']], function($router) {
$router->get('/profile', 'ProfileController@show');
$router->post('/settings', 'SettingsController@update');
});
Guard Specific Middleware
// Specify guard for routes
$router->middleware('auth:api')->group(function($router) {
$router->get('/api/user', 'ApiController@user');
});
// Multiple guards
$router->middleware('auth:web,api')->group(function($router) {
$router->get('/shared', 'SharedController@index');
});
Middleware Configuration
return [
'global' => [
\Yabasi\Middleware\StartSession::class,
],
'route' => [
'auth' => \Yabasi\Middleware\Authenticate::class,
'guest' => \Yabasi\Middleware\RedirectIfAuthenticated::class,
],
];
Custom Middleware
Create custom authentication middleware by implementing the MiddlewareInterface:
namespace App\Middleware;
use Yabasi\Middleware\MiddlewareInterface;
use Yabasi\Http\Request;
use Yabasi\Http\Response;
class CustomAuthMiddleware implements MiddlewareInterface
{
public function handle(Request $request, Closure $next): Response
{
if (!Auth::check()) {
// Custom authentication logic
if ($this->hasCustomToken($request)) {
// Validate custom token
return $next($request);
}
return new Response('Unauthorized', 401);
}
return $next($request);
}
protected function hasCustomToken(Request $request): bool
{
// Implement custom token validation
return false;
}
}
Register Custom Middleware
// In your service provider public function boot() { $this->app['middleware']->register('custom.auth', CustomAuthMiddleware::class); } // Usage in routes $router->middleware('custom.auth')->group(function($router) { // Protected routes });
Route Protection
Web Routes
// Protect web routes $router->middleware(['web', 'auth'])->group(function($router) { $router->get('/account', 'AccountController@show'); $router->post('/settings', 'SettingsController@update'); });
API Routes
// Protect API routes $router->middleware(['api', 'auth:api'])->group(function($router) { $router->get('/api/user', 'ApiController@user'); $router->post('/api/logout', 'ApiController@logout'); });
Advanced Protection
// Combining multiple middleware $router->middleware(['auth', 'verified', 'throttle:60,1']) ->group(function($router) { $router->post('/sensitive-action', 'SensitiveController@handle'); }); // Role-based protection $router->middleware(['auth', 'role:admin']) ->group(function($router) { $router->get('/admin', 'AdminController@dashboard'); });
Security Best Practices
- • Always protect sensitive routes with appropriate middleware
- • Combine authentication with rate limiting for enhanced security
- • Use role-based middleware for granular access control
- • Implement proper error handling for unauthorized access
Middleware Quick Reference
Built-in Middleware
'auth'
- Basic authentication'auth:api'
- API authentication'guest'
- Redirect if authenticated
Common Usage
- Route protection
- Group middleware
- Guard-specific auth
Examples
Practical examples of implementing authentication features in Yabasi Framework. These examples demonstrate real-world usage scenarios using the framework's built-in capabilities.
Complete Registration Flow
Registration Controller
namespace App\Middleware;
use Yabasi\Middleware\MiddlewareInterface;
use Yabasi\Http\Request;
use Yabasi\Http\Response;
class CustomAuthMiddleware implements MiddlewareInterface
{
public function handle(Request $request, Closure $next): Response
{
if (!Auth::check()) {
// Custom authentication logic
if ($this->hasCustomToken($request)) {
// Validate custom token
return $next($request);
}
return new Response('Unauthorized', 401);
}
return $next($request);
}
protected function hasCustomToken(Request $request): bool
{
// Implement custom token validation
return false;
}
}
Registration Form Template
<!-- register.twig --> {% raw %} <form method="POST" action="{{ url('register') }}" class="space-y-4"> {{ csrf_field() }} <div> <label for="name">Name</label> <input type="text" name="name" value="{{ old('name') }}" class="form-input" required> {% if errors.name %} <span class="text-red-500">{{ errors.name[0] }}</span> {% endif %} </div> <div> <label for="email">Email</label> <input type="email" name="email" value="{{ old('email') }}" class="form-input" required> {% if errors.email %} <span class="text-red-500">{{ errors.email[0] }}</span> {% endif %} </div> <button type="submit">Register</button> </form> {% endraw %}
Password Reset Flow
class PasswordResetController extends Controller
{
public function request(Request $request): Response
{
$validated = $request->validate([
'email' => 'required|email'
]);
$user = User::where('email', $validated['email'])->first();
if ($user) {
$token = Auth::createPasswordResetToken($user);
// Send password reset email with token
}
return $this->response->back()
->with('message', 'Password reset instructions sent');
}
public function reset(Request $request): Response
{
$validated = $request->validate([
'token' => 'required',
'password' => 'required|min:8|confirmed'
]);
if (Auth::resetPassword($validated['token'], $validated['password'])) {
return $this->response->redirect('/login')
->with('message', 'Password reset successful');
}
return $this->response->back()
->with('error', 'Invalid token');
}
}
Remember Me Implementation
public function login(Request $request): Response
{
$credentials = $request->validate([
'email' => 'required|email',
'password' => 'required',
'remember' => 'boolean'
]);
if (Auth::attempt($credentials, $credentials['remember'] ?? false)) {
$request->session()->regenerate();
return $this->response->redirect('/dashboard');
}
return $this->response->back()
->with('error', 'Invalid credentials');
}
Login Form with Remember Me
<!-- login.twig --> {% raw %} <form method="POST" action="{{ url('login') }}"> {{ csrf_field() }} <div class="mb-4"> <label for="email">Email</label> <input type="email" name="email" required> </div> <div class="mb-4"> <label for="password">Password</label> <input type="password" name="password" required> </div> <div class="mb-4"> <label> <input type="checkbox" name="remember"> Remember me </label> </div> <button type="submit">Login</button> </form> {% endraw %}
Important Notes
- • Always validate user input
- • Use CSRF protection for forms
- • Implement proper error handling
- • Consider rate limiting for authentication attempts
Best Practices
Follow these recommended practices to ensure secure, efficient, and maintainable authentication implementation in your Yabasi application.
Security Guidelines
Password Security
- Always use Auth::hash() for password hashing
- Enforce minimum password length (8+ characters)
- Never store plain-text passwords
Session Security
- Regenerate session IDs after login
- Use secure session settings
- Implement session timeout
// Good Practice
public function login(Request $request): Response
{
$credentials = $request->validate([
'email' => 'required|email',
'password' => 'required'
]);
if (Auth::attempt($credentials)) {
$request->session()->regenerate();
return $this->response->redirect('/dashboard');
}
// Rate limiting after failed attempts
Auth::incrementLoginAttempts($request);
return $this->response->back()
->with('error', 'Invalid credentials');
}
Performance Tips
Database Optimization
- Index authentication columns
- Use efficient queries
Caching Strategy
- Cache user permissions
- Use session storage efficiently
// Efficient database query
public function findByEmail(string $email): ?User
{
return User::where('email', $email)
->select(['id', 'email', 'password'])
->first();
}
// Caching user data
public function getUserPermissions(User $user): array
{
return Cache::remember("user.{$user->id}.permissions", 3600, function() use ($user) {
return $user->getPermissions();
});
}
Common Pitfalls
What to Avoid
- Storing sensitive data in sessions
- Skipping input validation
- Hardcoding credentials
Best Solutions
- Use environment variables for sensitive data
- Implement proper validation middleware
- Follow secure coding practices
Common Anti-Patterns to Avoid
// Bad Practice - Don't do this
if ($_POST['password'] === 'admin123') {
$_SESSION['is_admin'] = true;
}
// Instead, use proper authentication
if (Auth::attempt($credentials)) {
$request->session()->regenerate();
}
Quick Reference Checklist
Security
- Use HTTPS
- Implement CSRF protection
- Hash passwords
Performance
- Cache when possible
- Optimize queries
- Use proper indexes
Maintenance
- Follow naming conventions
- Document implementations
- Use configuration files