1. Go to this page and download the library: Download julienlinard/auth-php library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
// Login with "remember me" enabled
$auth->attempt($credentials, true);
use JulienLinard\Auth\Models\UserInterface;
$user = $em->getRepository(User::class)->find(1);
// Authenticate user directly
$auth->login($user);
// With "remember me"
$auth->login($user, true);
// Logout
$auth->logout();
// Check if a user is authenticated
if ($auth->check()) {
$user = $auth->user();
echo "Logged in user: " . $user->email;
}
// Check if no user is authenticated
if ($auth->guest()) {
echo "No user logged in";
}
// Get current user
$user = $auth->user(); // Returns UserInterface|null
// Get current user ID
$userId = $auth->id(); // Returns int|string|null
// Check if user has a specific role
if ($auth->hasRole('admin')) {
echo "User is administrator";
}
// Check multiple roles (OR)
if ($auth->hasRole('admin') || $auth->hasRole('moderator')) {
echo "User is admin or moderator";
}
// Check if user has a permission
if ($auth->can('edit-posts')) {
echo "User can edit posts";
}
// Check multiple permissions (OR)
if ($auth->can('edit-posts') || $auth->can('delete-posts')) {
echo "User can edit or delete posts";
}
use JulienLinard\Doctrine\Mapping\Entity;
use JulienLinard\Doctrine\Mapping\Column;
use JulienLinard\Doctrine\Mapping\Id;
use JulienLinard\Auth\Models\UserInterface;
use JulienLinard\Auth\Models\Authenticatable;
#[Entity(table: 'users')]
class User implements UserInterface
{
use Authenticatable;
#[Id]
#[Column(type: 'integer', autoIncrement: true)]
public ?int $id = null;
#[Column(type: 'string', length: 255)]
public string $email;
#[Column(type: 'string', length: 255)]
public string $password;
#[Column(type: 'string', length: 255, nullable: true)]
public ?string $firstname = null;
#[Column(type: 'string', length: 50, nullable: true)]
public ?string $role = null; // 'admin', 'user', 'moderator', etc.
// Roles (can be a string or an array)
public function getAuthRoles(): array|string
{
return $this->role ?? 'user';
}
// Permissions (returns an array)
public function getAuthPermissions(): array
{
// Example: permissions based on role
return match($this->role) {
'admin' => ['edit-posts', 'delete-posts', 'manage-users'],
'moderator' => ['edit-posts', 'delete-posts'],
'user' => ['view-posts'],
default => []
};
}
}
use JulienLinard\Auth\Middleware\AuthMiddleware;
use JulienLinard\Router\Router;
$router = new Router();
$auth = new AuthManager($authConfig);
// Protected route with AuthMiddleware (default redirect to '/login')
class DashboardController
{
#[Route(
path: '/dashboard',
methods: ['GET'],
name: 'dashboard',
middleware: [new AuthMiddleware()]
)]
public function index(): Response
{
return new Response(200, '<h1>Dashboard</h1>');
}
}
// With custom redirect route
#[Route(
path: '/dashboard',
methods: ['GET'],
middleware: [new AuthMiddleware('/connexion')]
)]
// AuthManager is automatically retrieved from container if not provided
// You can also pass it explicitly:
#[Route(
path: '/dashboard',
methods: ['GET'],
middleware: [new AuthMiddleware('/login', $auth)]
)]
use JulienLinard\Auth\Middleware\RoleMiddleware;
// Route protected by role (default: returns JSON error for unauthorized)
class AdminController
{
#[Route(
path: '/admin/users',
methods: ['GET'],
name: 'admin.users',
middleware: [
new AuthMiddleware(),
new RoleMiddleware('admin')
]
)]
public function users(): Response
{
return Response::json(['users' => []]);
}
}
// With multiple accepted roles
#[Route(
path: '/moderate',
methods: ['GET'],
middleware: [
new AuthMiddleware(),
new RoleMiddleware(['admin', 'moderator'])
]
)]
// With custom redirect route (for GET requests)
#[Route(
path: '/admin',
methods: ['GET'],
middleware: [
new AuthMiddleware(),
new RoleMiddleware('admin', '/unauthorized')
]
)]
use JulienLinard\Auth\Middleware\PermissionMiddleware;
// Route protected by permission (default: returns JSON error for unauthorized)
class PostController
{
#[Route(
path: '/posts/{id}/edit',
methods: ['POST'],
middleware: [
new AuthMiddleware(),
new PermissionMiddleware('edit-posts')
]
)]
public function update(Request $request): Response
{
// User has 'edit-posts' permission
return Response::json(['message' => 'Post updated']);
}
}
// With multiple accepted permissions
#[Route(
path: '/posts/{id}/delete',
methods: ['DELETE'],
middleware: [
new AuthMiddleware(),
new PermissionMiddleware(['delete-posts', 'manage-posts'])
]
)]
// With custom redirect route (for GET requests)
#[Route(
path: '/posts/{id}/edit',
methods: ['GET'],
middleware: [
new AuthMiddleware(),
new PermissionMiddleware('edit-posts', '/forbidden')
]
)]
use JulienLinard\Auth\Middleware\GuestMiddleware;
class AuthController
{
// Default redirect to '/' if user is already authenticated
#[Route(
path: '/login',
methods: ['GET'],
middleware: [new GuestMiddleware()]
)]
public function loginForm(): Response
{
// Only unauthenticated users can access
return new Response(200, '<form>...</form>');
}
// With custom redirect route
#[Route(
path: '/register',
methods: ['GET'],
middleware: [new GuestMiddleware('/dashboard')]
)]
public function registerForm(): Response
{
// If user is authenticated, redirect to '/dashboard'
return new Response(200, '<form>...</form>');
}
}
use JulienLinard\Router\Router;
$router = new Router();
$auth = new AuthManager($authConfig);
// Route group protected by authentication
$router->group('/dashboard', [new AuthMiddleware()], function($router) {
$router->registerRoutes(DashboardController::class);
});
// Route group protected by admin role with custom redirect
$router->group('/admin', [
new AuthMiddleware(),
new RoleMiddleware('admin', '/unauthorized')
], function($router) {
$router->registerRoutes(AdminController::class);
});
// Route group protected by permission with custom redirect
$router->group('/posts', [
new AuthMiddleware(),
new PermissionMiddleware('edit-posts', '/forbidden')
], function($router) {
$router->registerRoutes(PostController::class);
});
use JulienLinard\Auth\Providers\DatabaseUserProvider;
use JulienLinard\Doctrine\EntityManager;
$em = new EntityManager($dbConfig);
// Manual creation (optional, created automatically by default)
$provider = new DatabaseUserProvider(
$em,
User::class,
'id', // Identifier field
'email' // Credential field
);
$authConfig = [
'user_class' => User::class,
'entity_manager' => $em,
'provider' => $provider
];
use JulienLinard\Auth\Providers\UserProviderInterface;
use JulienLinard\Auth\Models\UserInterface;
class ApiUserProvider implements UserProviderInterface
{
public function findById(int|string $identifier): ?UserInterface
{
// Retrieve from external API
$response = file_get_contents("https://api.example.com/users/{$identifier}");
$data = json_decode($response, true);
if ($data) {
return new User($data);
}
return null;
}
public function findByCredentials(array $credentials): ?UserInterface
{
// Retrieve from external API with credentials
$email = $credentials['email'] ?? null;
if (!$email) {
return null;
}
$response = file_get_contents("https://api.example.com/users?email={$email}");
$data = json_decode($response, true);
if ($data && isset($data[0])) {
return new User($data[0]);
}
return null;
}
}
// Usage
$authConfig = [
'user_class' => User::class,
'provider' => new ApiUserProvider()
];
use JulienLinard\Auth\Guards\SessionGuard;
use JulienLinard\Auth\Providers\DatabaseUserProvider;
use JulienLinard\Auth\Hashers\PasswordHasher;
$provider = new DatabaseUserProvider($em, User::class);
$hasher = new PasswordHasher(PASSWORD_BCRYPT);
$guard = new SessionGuard($provider, $hasher, 'auth_user');
// The guard is created automatically by AuthManager
// But you can customize it if needed
use JulienLinard\Auth\Guards\GuardInterface;
use JulienLinard\Auth\Models\UserInterface;
use JulienLinard\Auth\Providers\UserProviderInterface;
use JulienLinard\Auth\Hashers\HasherInterface;
class JwtGuard implements GuardInterface
{
public function __construct(
private UserProviderInterface $userProvider,
private HasherInterface $hasher
) {}
public function attempt(array $credentials, bool $remember = false): bool
{
$user = $this->userProvider->findByCredentials($credentials);
if ($user === null) {
return false;
}
if (!isset($credentials['password'])) {
return false;
}
if (!$this->hasher->verify($credentials['password'], $user->getAuthPassword())) {
return false;
}
// Create a JWT token instead of using session
$token = $this->createJwtToken($user);
setcookie('auth_token', $token, time() + 3600);
return true;
}
public function check(): bool
{
$token = $_COOKIE['auth_token'] ?? null;
if (!$token) {
return false;
}
$userId = $this->decodeJwtToken($token);
return $userId !== null;
}
public function user(): ?UserInterface
{
$token = $_COOKIE['auth_token'] ?? null;
if (!$token) {
return null;
}
$userId = $this->decodeJwtToken($token);
if (!$userId) {
return null;
}
return $this->userProvider->findById($userId);
}
// ... other methods
use JulienLinard\Auth\Hashers\PasswordHasher;
// With default algorithm (BCRYPT)
$hasher = new PasswordHasher();
// With specific algorithm
$hasher = new PasswordHasher(PASSWORD_ARGON2ID);
// With custom options
$hasher = new PasswordHasher(PASSWORD_ARGON2ID, [
'memory_cost' => 65536,
'time_cost' => 4,
'threads' => 3
]);
// Usage
$password = 'password123';
$hash = $hasher->hash($password);
$isValid = $hasher->verify($password, $hash);
$needsRehash = $hasher->needsRehash($hash);
use JulienLinard\Auth\Hashers\HasherInterface;
class CustomHasher implements HasherInterface
{
public function hash(string $password): string
{
// Your custom hash logic
return hash('sha256', $password . 'salt');
}
public function verify(string $password, string $hash): bool
{
return hash('sha256', $password . 'salt') === $hash;
}
public function needsRehash(string $hash): bool
{
// Your logic to determine if rehash is needed
return false;
}
}
// Usage
$authConfig = [
'user_class' => User::class,
'entity_manager' => $em,
'hasher' => new CustomHasher()
];
use JulienLinard\Core\Application;
use JulienLinard\Doctrine\EntityManager;
use JulienLinard\Auth\AuthManager;
// Initialize the application
$app = Application::create(__DIR__);
$app->loadEnv();
// Configure database
$em = new EntityManager([
'host' => $_ENV['DB_HOST'],
'dbname' => $_ENV['DB_NAME'],
'user' => $_ENV['DB_USER'],
'password' => $_ENV['DB_PASS']
]);
// Configure authentication
$auth = new AuthManager([
'user_class' => User::class,
'entity_manager' => $em
]);
// Use in a controller
class HomeController extends \JulienLinard\Core\Controller\Controller
{
public function index(AuthManager $auth)
{
if ($auth->check()) {
$user = $auth->user();
return $this->view('dashboard', ['user' => $user]);
}
return $this->redirect('/login');
}
}
use JulienLinard\Doctrine\EntityManager;
use JulienLinard\Doctrine\Mapping\Entity;
use JulienLinard\Doctrine\Mapping\Column;
use JulienLinard\Doctrine\Mapping\Id;
use JulienLinard\Auth\Models\UserInterface;
use JulienLinard\Auth\Models\Authenticatable;
// Define the User entity
#[Entity(table: 'users')]
class User implements UserInterface
{
use Authenticatable;
#[Id]
#[Column(type: 'integer', autoIncrement: true)]
public ?int $id = null;
#[Column(type: 'string', length: 255)]
public string $email;
#[Column(type: 'string', length: 255)]
public string $password;
// ... other properties
}
// Use with AuthManager
$em = new EntityManager($dbConfig);
$auth = new AuthManager([
'user_class' => User::class,
'entity_manager' => $em
]);
use JulienLinard\Router\Router;
use JulienLinard\Router\Attributes\Route;
use JulienLinard\Auth\AuthManager;
use JulienLinard\Auth\Middleware\AuthMiddleware;
use JulienLinard\Auth\Middleware\RoleMiddleware;
$router = new Router();
$auth = new AuthManager($authConfig);
// Public routes
class HomeController
{
#[Route(path: '/', methods: ['GET'], name: 'home')]
public function index(): Response
{
return new Response(200, '<h1>Home</h1>');
}
}
// Protected routes
class DashboardController
{
#[Route(
path: '/dashboard',
methods: ['GET'],
name: 'dashboard',
middleware: [new AuthMiddleware($auth)]
)]
public function index(): Response
{
return new Response(200, '<h1>Dashboard</h1>');
}
}
// Routes with roles
class AdminController
{
#[Route(
path: '/admin',
methods: ['GET'],
name: 'admin',
middleware: [
new AuthMiddleware($auth),
new RoleMiddleware('admin', $auth)
]
)]
public function index(): Response
{
return new Response(200, '<h1>Admin</h1>');
}
}
// Register routes
$router->registerRoutes(HomeController::class);
$router->registerRoutes(DashboardController::class);
$router->registerRoutes(AdminController::class);