bridgewatercollege/custom-login-bundle
Installation
composer require bridgewatercollege/custom-login-bundle
Add to config/bundles.php:
BridgewaterCollege\CustomLoginBundle\BridgewaterCollegeCustomLoginBundle::class => ['all' => true],
Publish Configuration
php bin/console bridgewater-college:custom-login:install
This generates:
config/packages/bridgewater_college_custom_login.yaml (default config)templates/bridgewater_college_custom_login/Basic Usage
Define a login system in config/packages/bridgewater_college_custom_login.yaml:
bridgewater_college_custom_login:
systems:
default:
type: "form" # or "oauth", "api_key"
form:
path: /login
template: bridgewater_college_custom_login/login.html.twig
handler: App\Security\CustomLoginHandler
First Login Route
Access /login (or your defined path) to test the default form-based login.
Define Systems: Configure each login method (form, OAuth, API key) in config/packages/bridgewater_college_custom_login.yaml:
systems:
oauth_google:
type: "oauth"
provider: "google"
client_id: "%env(GOOGLE_CLIENT_ID)%"
client_secret: "%env(GOOGLE_CLIENT_SECRET)%"
redirect_route: "app_verify_google"
api_key:
type: "api_key"
path: "/api/login"
handler: App\Security\ApiKeyHandler
Route Integration:
# config/routes.yaml
bridgewater_college_custom_login:
resource: "@BridgewaterCollegeCustomLoginBundle/Resources/config/routing.yaml"
BridgewaterCollege\CustomLoginBundle\Security\LoginHandlerInterface:
namespace App\Security;
use BridgewaterCollege\CustomLoginBundle\Security\LoginHandlerInterface;
use Symfony\Component\HttpFoundation\Request;
class CustomLoginHandler implements LoginHandlerInterface {
public function handle(Request $request) {
$email = $request->request->get('email');
$password = $request->request->get('password');
// Custom logic (e.g., LDAP, database, or external API)
return $user; // Return a User object or throw an exception
}
}
systems:
custom:
type: "form"
handler: App\Security\CustomLoginHandler
config/packages/bridgewater_college_custom_login.yaml:
systems:
oauth_github:
type: "oauth"
provider: "github"
client_id: "%env(GITHUB_CLIENT_ID)%"
client_secret: "%env(GITHUB_CLIENT_SECRET)%"
scope: ["user:email"]
app_verify_github) to handle OAuth callbacks.systems:
api_key:
type: "api_key"
path: "/api/login"
handler: App\Security\ApiKeyHandler
ApiKeyHandler:
public function handle(Request $request) {
$apiKey = $request->headers->get('X-API-KEY');
if ($this->validateApiKey($apiKey)) {
return $this->userProvider->loadUserByUsername($apiKey);
}
throw new \RuntimeException('Invalid API key');
}
vendor/bridgewatercollege/custom-login-bundle/templates/bridgewater_college_custom_login/
to:
templates/bridgewater_college_custom_login/.// src/EventListener/CustomLoginListener.php
use BridgewaterCollege\CustomLoginBundle\Event\LoginEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class CustomLoginListener implements EventSubscriberInterface {
public static function getSubscribedEvents() {
return [
LoginEvent::LOGIN_SUCCESS => 'onLoginSuccess',
];
}
public function onLoginSuccess(LoginEvent $event) {
// Log, audit, or trigger post-login actions
}
}
Configuration Overrides
bridgewater_college_custom_login.yaml is merged correctly. Use !import or !include sparingly to avoid conflicts.php bin/console debug:config bridgewater_college_custom_login.Handler Misconfiguration
public function handle(Request $request) {
try {
// Logic
} catch (\Exception $e) {
throw new \RuntimeException('Login failed: ' . $e->getMessage());
}
}
OAuth Redirect URI Mismatch
hwi-oauth) may conflict with this bundle’s OAuth routes.redirect_route in config and ensure it matches your route name.Template Caching
php bin/console cache:clear
CSRF Protection
{{ form_start(form, { 'attr': {'novalidate': 'novalidate'} }) }}
{{ form_row(form._token) }} {# CSRF token #}
User Provider Assumptions
User object is returned. If using a custom provider (e.g., LDAP), ensure it returns an object compatible with Symfony’s UserInterface.Enable Debug Mode
Set APP_DEBUG=true in .env to see detailed errors and logs.
Log Events
Subscribe to LoginEvent::LOGIN_FAILURE to log failed attempts:
public static function getSubscribedEvents() {
return [
LoginEvent::LOGIN_FAILURE => 'onLoginFailure',
];
}
Check Routes Verify routes are loaded:
php bin/console debug:router | grep custom_login
Validate Config Use the debug command to validate your config:
php bin/console debug:config bridgewater_college_custom_login
Custom Login Types
Extend the bundle by adding new type handlers. Implement LoginHandlerInterface and register in config:
systems:
custom_type:
type: "custom_type"
handler: App\Security\CustomTypeHandler
Event-Driven Logic Dispatch custom events in handlers:
$dispatcher->dispatch(new CustomLoginEvent($user, $request));
Multi-Factor Authentication (MFA) Chain handlers or use events to integrate MFA (e.g., TOTP) after successful login.
Rate Limiting
Use Symfony’s RateLimiter or a library like symfony/throttler to limit login attempts per IP:
use Symfony\Component\Security\Http\Firewall\RateLimiterInterface;
class CustomLoginHandler implements LoginHandlerInterface {
private $rateLimiter;
public function __construct(RateLimiterInterface $rateLimiter) {
$this->rateLimiter = $rateLimiter;
}
public function handle(Request $request) {
$this->rateLimiter->check($request->getClientIp());
// Rest of logic
}
}
Localization
Override translation files in translations/ to customize messages (e.g., "Invalid credentials").
How can I help you explore Laravel packages today?