1. Go to this page and download the library: Download tobento/app-user 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/ */
tobento / app-user example snippets
use Tobento\App\AppFactory;
// Create the app
$app = (new AppFactory())->createApp();
// Adding boots
$app->boot(\Tobento\App\User\Boot\User::class);
// Run the app
$app->run();
use Tobento\App\AppFactory;
use Tobento\App\User\UserRepositoryInterface;
use Tobento\App\User\UserFactoryInterface;
use Tobento\App\User\AddressRepositoryInterface;
use Tobento\App\User\AddressFactoryInterface;
use Tobento\App\User\RoleRepositoryInterface;
use Tobento\App\User\RoleFactoryInterface;
use Tobento\Service\Repository\RepositoryInterface;
$app = (new AppFactory())->createApp();
// Add directories:
$app->dirs()
->dir(realpath(__DIR__.'/../'), 'root')
->dir(realpath(__DIR__.'/../app/'), 'app')
->dir($app->dir('app').'config', 'config', group: 'config')
->dir($app->dir('root').'public', 'public')
->dir($app->dir('root').'vendor', 'vendor');
// Adding boots:
$app->boot(\Tobento\App\User\Boot\User::class);
$app->booting();
// User:
$userRepository = $app->get(UserRepositoryInterface::class);
// var_dump($userRepository instanceof RepositoryInterface);
// bool(true)
$userFactory = $app->get(UserFactoryInterface::class);
// Address:
$addressRepository = $app->get(AddressRepositoryInterface::class);
// var_dump($addressRepository instanceof RepositoryInterface);
// bool(true)
$addressFactory = $app->get(AddressFactoryInterface::class);
// Role:
$roleRepository = $app->get(RoleRepositoryInterface::class);
// var_dump($roleRepository instanceof RepositoryInterface);
// bool(true)
$roleFactory = $app->get(RoleFactoryInterface::class);
// Run the app:
$app->run();
use Tobento\App\AppFactory;
use Tobento\App\User\Authentication\AuthInterface;
use Tobento\App\User\Authentication\Token\TokenStoragesInterface;
use Tobento\App\User\Authentication\Token\TokenStorageInterface;
use Tobento\App\User\Authentication\Token\TokenTransportsInterface;
use Tobento\App\User\Authentication\Token\TokenTransportInterface;
use Tobento\App\User\Authenticator\TokenAuthenticatorInterface;
use Tobento\App\User\Authenticator\UserVerifierInterface;
$app = (new AppFactory())->createApp();
// Add directories:
$app->dirs()
->dir(realpath(__DIR__.'/../'), 'root')
->dir(realpath(__DIR__.'/../app/'), 'app')
->dir($app->dir('app').'config', 'config', group: 'config')
->dir($app->dir('root').'public', 'public')
->dir($app->dir('root').'vendor', 'vendor');
// Adding boots:
$app->boot(\Tobento\App\User\Boot\User::class);
$app->booting();
// Auth:
$auth = $app->get(AuthInterface::class);
// Token storages:
$tokenStorages = $app->get(TokenStoragesInterface::class);
// Default token storage:
$tokenStorage = $app->get(TokenStorageInterface::class);
// Token transports:
$tokenTransports = $app->get(TokenTransportsInterface::class);
// Default token transport:
$tokenTransport = $app->get(TokenTransportInterface::class);
// Default token authenticator:
$tokenAuthenticator = $app->get(TokenAuthenticatorInterface::class);
// Default user verifier:
$userVerifier = $app->get(UserVerifierInterface::class);
// Run the app:
$app->run();
use Tobento\App\AppFactory;
use Tobento\App\User\UserInterface;
use Tobento\Service\User\UserInterface as ServiceUserInterface;
use Tobento\Service\Acl\Authorizable;
use Psr\Http\Message\ServerRequestInterface;
$app = (new AppFactory())->createApp();
// Add directories:
$app->dirs()
->dir(realpath(__DIR__.'/../'), 'root')
->dir(realpath(__DIR__.'/../app/'), 'app')
->dir($app->dir('app').'config', 'config', group: 'config')
->dir($app->dir('root').'public', 'public')
->dir($app->dir('root').'vendor', 'vendor');
// Adding boots:
$app->boot(\Tobento\App\Http\Boot\Routing::class);
$app->boot(\Tobento\App\User\Boot\User::class);
$app->booting();
// Routes:
$app->route('GET', 'user', function(ServerRequestInterface $request) {
// Get the current user (may be authenticated or not):
$user = $request->getAttribute(UserInterface::class);
// var_dump($user instanceof UserInterface);
// bool(true)
// var_dump($user instanceof ServiceUserInterface);
// bool(true)
// var_dump($user instanceof Authorizable);
// bool(true)
// Check if authenticated:
$user->isAuthenticated();
// bool(false)
return $user?->toArray();
});
// Run the app:
$app->run();
use Tobento\App\AppFactory;
use Tobento\App\User\UserInterface;
use Tobento\App\User\Authentication\AuthInterface;
use Tobento\App\User\Authentication\AuthenticatedInterface;
use Tobento\App\User\Authentication\Token\TokenInterface;
use Tobento\Service\User\UserInterface as ServiceUserInterface;
use Tobento\Service\Acl\Authorizable;
use Psr\Http\Message\ServerRequestInterface;
$app = (new AppFactory())->createApp();
// Add directories:
$app->dirs()
->dir(realpath(__DIR__.'/../'), 'root')
->dir(realpath(__DIR__.'/../app/'), 'app')
->dir($app->dir('app').'config', 'config', group: 'config')
->dir($app->dir('root').'public', 'public')
->dir($app->dir('root').'vendor', 'vendor');
// Adding boots:
$app->boot(\Tobento\App\Http\Boot\Routing::class);
$app->boot(\Tobento\App\User\Boot\User::class);
$app->booting();
// Routes:
$app->route('GET', 'user', function(ServerRequestInterface $request) {
// Get the auth:
$auth = $request->getAttribute(AuthInterface::class);
// var_dump($auth instanceof AuthInterface);
// bool(true)
// You may check if user is authenticated:
if ($auth->hasAuthenticated()) {
return null;
}
// Get authenticated:
$authenticated = $auth->getAuthenticated();
// var_dump($auth->getAuthenticated() instanceof AuthenticatedInterface);
// bool(true)
// Get the authenticated user:
$user = $authenticated->user();
// var_dump($user instanceof UserInterface);
// bool(true)
// var_dump($user instanceof ServiceUserInterface);
// bool(true)
// var_dump($user instanceof Authorizable);
// bool(true)
// Get the authenticated token:
$token = $authenticated->token();
// var_dump($token instanceof TokenInterface);
// bool(true)
// Get the authenticated via:
// var_dump($authenticated->via());
// string(9) "loginlink"
// Get the authenticated by (authenticator class name):
// var_dump($authenticated->by());
// string(52) "Tobento\App\User\Authenticator\IdentityAuthenticator"
return $user;
});
// Run the app:
$app->run();
use Tobento\App\User\UserRepositoryInterface;
use Tobento\App\User\Authentication\AuthInterface;
use Tobento\App\User\Authentication\Authenticated;
use Tobento\App\User\Authentication\Token\TokenStorageInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
class AuthController
{
public function authenticate(
ServerRequestInterface $request,
UserRepositoryInterface $userRepository,
AuthInterface $auth,
TokenStorageInterface $tokenStorage,
): ResponseInterface {
// You may check if user is authenticated:
// Or use the \Tobento\App\User\Middleware\Unauthenticated::class to do so.
if ($auth->hasAuthenticated()) {
// create and return response if is already authenticated.
}
// authenticate user manually:
$user = $userRepository->findById(1);
if (is_null($user)) {
// create and return response if user does not exist.
}
// create token and start auth:
$token = $tokenStorage->createToken(
// Set the payload:
payload: ['userId' => $user->id(), 'passwordHash' => $user->password()],
// Set the name of which the user was authenticated via:
authenticatedVia: 'login.auth', // The name is up to you.
// Set the name of which the user was authenticated by (authenticator name) or null if none:
authenticatedBy: null,
// Set the point in time the token has been issued or null (now):
issuedAt: new \DateTimeImmutable('now'),
// Set the point in time after which the token MUST be considered expired or null:
// The time might depend on the token storage e.g. session expiration!
expiresAt: new \DateTimeImmutable('now +10 minutes'),
);
$auth->start(new Authenticated(token: $token, user: $user));
// create and return response:
return $createdResponse;
}
}
use Tobento\App\User\Authentication\AuthInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
class AuthController
{
public function unauthenticate(
AuthInterface $auth,
): ResponseInterface {
$auth->close();
// create and return response:
return $createdResponse;
}
}
use Tobento\App\AppFactory;
use Tobento\Service\Acl\AclInterface;
// Create the app
$app = (new AppFactory())->createApp();
// Adding boots
// The acl boot gets booted automatically by the user boot:
// $app->boot(\Tobento\App\User\Boot\Acl::class);
$app->boot(\Tobento\App\User\Boot\User::class);
$acl = $app->get(AclInterface::class);
// Run the app
$app->run();
use Tobento\Service\Migration\MigrationInterface;
use Tobento\Service\Migration\ActionsInterface;
use Tobento\Service\Migration\Actions;
use Tobento\Service\Repository\Storage\Migration\RepositoryAction;
use Tobento\Service\Repository\Storage\Migration\RepositoryDeleteAction;
use Tobento\App\User\RoleRepositoryInterface;
class RolesStorageMigration implements MigrationInterface
{
public function __construct(
protected RoleRepositoryInterface $roleRepository,
) {}
/**
* Return a description of the migration.
*
* @return string
*/
public function description(): string
{
return 'User roles.';
}
/**
* Return the actions to be processed on install.
*
* @return ActionsInterface
*/
public function install(): ActionsInterface
{
return new Actions(
RepositoryAction::newOrNull(
repository: $this->roleRepository,
description: 'Default roles',
items: [
['key' => 'guest', 'areas' => ['frontend'], 'active' => true],
['key' => 'registered', 'areas' => ['frontend'], 'active' => true],
['key' => 'business', 'areas' => ['frontend'], 'active' => true],
['key' => 'developer', 'areas' => ['backend'], 'active' => true],
['key' => 'administrator', 'areas' => ['backend'], 'active' => true],
['key' => 'editor', 'areas' => ['backend'], 'active' => true],
],
),
);
}
/**
* Return the actions to be processed on uninstall.
*
* @return ActionsInterface
*/
public function uninstall(): ActionsInterface
{
return new Actions();
}
}
use Tobento\App\AppFactory;
use Tobento\Service\Acl\AclInterface;
// Create the app
$app = (new AppFactory())->createApp();
// Adding boots
// The acl boot gets booted automatically by
// the user boot:
// $app->boot(\Tobento\App\User\Boot\Acl::class);
$app->boot(\Tobento\App\User\Boot\User::class);
$acl = $app->get(AclInterface::class);
$acl->rule('articles.read')
->title('Article Read')
->description('If a user can read articles');
// Run the app
$app->run();
use Tobento\App\Boot;
use Tobento\App\User\Boot\Acl;
class AnyServiceBoot extends Boot
{
public const BOOT = [
// you may ensure the acl boot.
Acl::class,
];
public function boot(Acl $acl)
{
$acl->rule('articles.read')
->title('Article Read')
->description('If a user can read articles');
}
}
use Tobento\Service\Acl\AclInterface;
class ArticleController
{
public function index(AclInterface $acl): string
{
if ($acl->cant('articles.read')) {
return 'can not read';
}
return 'can read';
}
}
use Tobento\App\User\UserInterface;
use Psr\Http\Message\ServerRequestInterface;
class ArticleController
{
public function index(ServerRequestInterface $request): string
{
$user = $request->getAttribute(UserInterface::class);
if ($user->cant('articles.read')) {
return 'can not read';
}
return 'can read';
}
}
use Tobento\Service\Acl\AclInterface;
class ArticleController
{
public function index(AclInterface $acl): string
{
$user = $this->acl->getCurrentUser();
if (
$user
&& $user->hasRole()
&& $user->role()->key() !== 'editor'
) {
return 'can not read';
}
// or
if ($user?->getRoleKey() !== 'editor') {
return 'can not read';
}
return 'can read';
}
}
use Tobento\App\User\UserInterface;
use Psr\Http\Message\ServerRequestInterface;
class ArticleController
{
public function index(ServerRequestInterface $request): string
{
$user = $request->getAttribute(UserInterface::class);
if ($user->hasRole() && $user->role()->key() !== 'editor') {
return 'can not read';
}
// or
if ($user->getRoleKey() !== 'editor') {
return 'can not read';
}
return 'can read';
}
}
use Tobento\App\AppFactory;
// Create the app
$app = (new AppFactory())->createApp();
// Adding boots
$app->boot(\Tobento\App\User\Boot\HttpUserErrorHandler::class);
$app->boot(\Tobento\App\User\Boot\User::class);
// Run the app
$app->run();
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
// Get the authenticated user if exists:
$user = $request->getAttribute(AuthInterface::class)?->getAuthenticated()?->user();
// Otherwise, create guest user:
if (is_null($user)) {
$user = $this->userFactory->createGuestUser();
}
$request = $request->withAttribute(UserInterface::class, $user);
// Set user on acl:
if ($this->acl) {
$this->acl->setCurrentUser($user);
}
return $handler->handle($request);
}
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
// Add auth to the request:
$request = $request->withAttribute(AuthInterface::class, $this->auth);
// Handle token:
$tokenId = $this->tokenTransport->fetchTokenId($request);
if (!is_null($tokenId)) {
try {
$token = $this->tokenStorage->fetchToken($tokenId);
$user = $this->tokenAuthenticator->authenticate($token);
$this->auth->start(
new Authenticated(token: $token, user: $user),
$this->tokenTransport->name()
);
} catch (TokenNotFoundException $e) {
// ignore TokenNotFoundException as to
// proceed with handling the response.
// other exceptions will be handled by the error handler!
}
}
// Handle the response:
$response = $handler->handle($request);
if (! $this->auth->hasAuthenticated()) {
return $response;
}
if ($this->auth->isClosed()) {
$this->tokenStorage->deleteToken($this->auth->getAuthenticated()->token());
return $this->tokenTransport->removeToken(
token: $this->auth->getAuthenticated()->token(),
request: $request,
response: $response,
);
}
return $this->tokenTransport->commitToken(
token: $this->auth->getAuthenticated()->token(),
request: $request,
response: $response,
);
}
use Tobento\App\AppFactory;
use Tobento\App\User\Middleware\Authenticated;
$app = (new AppFactory())->createApp();
// Add directories:
$app->dirs()
->dir(realpath(__DIR__.'/../'), 'root')
->dir(realpath(__DIR__.'/../app/'), 'app')
->dir($app->dir('app').'config', 'config', group: 'config')
->dir($app->dir('root').'public', 'public')
->dir($app->dir('root').'vendor', 'vendor');
// Adding boots:
$app->boot(\Tobento\App\Http\Boot\Routing::class);
$app->boot(\Tobento\App\User\Boot\User::class);
$app->booting();
// Routes:
$app->route('GET', 'account', function() {
// only for authenticated user!
return 'response';
})->middleware(Authenticated::class)->name('account');
$app->route('GET', 'account', function() {
// only for authenticated user!
return 'response';
})->middleware([
Authenticated::class,
// you may allow access only to user authenticated via:
'via' => 'loginform|loginlink',
// or you may allow access only to user authenticated except via:
'exceptVia' => 'remembered|loginlink',
// you may specify a custom message to show to the user:
'message' => 'You have insufficient rights to access the resource!',
// you may specify a message level:
'messageLevel' => 'notice',
// you may specify a route name for redirection:
'redirectRoute' => 'login',
// or you may specify an uri for redirection
'redirectUri' => '/login',
]);
// you may use the middleware alias defined in user config:
$app->route('GET', 'account', function() {
return 'response';
})->middleware(['auth', 'via' => 'loginform|loginlink']);
// Run the app:
$app->run();
use Tobento\App\AppFactory;
use Tobento\App\User\Middleware\Unauthenticated;
$app = (new AppFactory())->createApp();
// Add directories:
$app->dirs()
->dir(realpath(__DIR__.'/../'), 'root')
->dir(realpath(__DIR__.'/../app/'), 'app')
->dir($app->dir('app').'config', 'config', group: 'config')
->dir($app->dir('root').'public', 'public')
->dir($app->dir('root').'vendor', 'vendor');
// Adding boots:
$app->boot(\Tobento\App\Http\Boot\Routing::class);
$app->boot(\Tobento\App\User\Boot\User::class);
$app->booting();
// Routes:
$app->route('GET', 'login', function() {
// only for unauthenticated user!
return 'response';
})->middleware(Unauthenticated::class)->name('login');
$app->route('GET', 'login', function() {
// only for unauthenticated user!
return 'response';
})->middleware([
Unauthenticated::class,
// you may allow access only to user authenticated via:
'via' => 'remembered|loginlink',
// or you may allow access only to user authenticated except via:
'exceptVia' => 'remembered|loginlink',
// you may specify a custom message to show to the user:
'message' => 'Already authenticated!',
// you may specify a message level:
'messageLevel' => 'notice',
// you may specify a route name for redirection:
'redirectRoute' => 'home',
// or you may specify an uri for redirection
'redirectUri' => '/home',
]);
// you may use the middleware alias defined in user config:
$app->route('GET', 'login', function() {
return 'response';
})->middleware(['guest', 'message' => 'Already authenticated!']);
// Run the app:
$app->run();
use Tobento\App\AppFactory;
use Tobento\App\User\Middleware\Verified;
$app = (new AppFactory())->createApp();
// Add directories:
$app->dirs()
->dir(realpath(__DIR__.'/../'), 'root')
->dir(realpath(__DIR__.'/../app/'), 'app')
->dir($app->dir('app').'config', 'config', group: 'config')
->dir($app->dir('root').'public', 'public')
->dir($app->dir('root').'vendor', 'vendor');
// Adding boots:
$app->boot(\Tobento\App\Http\Boot\Routing::class);
$app->boot(\Tobento\App\User\Boot\User::class);
$app->booting();
// Routes:
$app->route('GET', 'account', function() {
// only for users with at least one channel verified!
return 'response';
})->middleware(Verified::class)->name('account');
$app->route('GET', 'account', function() {
// only for users with specific channels verified!
return 'response';
})->middleware([
Verified::class,
// specify the channels the user must have at least verified one of:
'oneOf' => 'email|smartphone',
// OR specify the channels the user must have verified all:
'allOf' => 'email|smartphone',
// you may specify a custom message to show to the user:
'message' => 'You are not verified to access the resource!',
// you may specify a message level:
'messageLevel' => 'notice',
// you may specify a route name for redirection:
'redirectRoute' => 'login',
// or you may specify an uri for redirection
'redirectUri' => '/login',
]);
// you may use the middleware alias defined in user config:
$app->route('GET', 'account', function() {
return 'response';
})->middleware(['verified', 'oneOf' => 'email|smartphone']);
// Run the app:
$app->run();
use Tobento\App\AppFactory;
use Tobento\App\User\Middleware\VerifyPermission;
$app = (new AppFactory())->createApp();
// Add directories:
$app->dirs()
->dir(realpath(__DIR__.'/../'), 'root')
->dir(realpath(__DIR__.'/../app/'), 'app')
->dir($app->dir('app').'config', 'config', group: 'config')
->dir($app->dir('root').'public', 'public')
->dir($app->dir('root').'vendor', 'vendor');
// Adding boots:
$app->boot(\Tobento\App\Http\Boot\Routing::class);
$app->boot(\Tobento\App\User\Boot\User::class);
$app->booting();
// Routes:
$app->route('GET', 'login', function() {
// only for user with permission login.show!
return 'response';
})->middleware(VerifyPermission::class)->name('login.show');
// you may specify the following parameters:
$app->route('GET', 'login', function() {
return 'response';
})->middleware([
VerifyPermission::class,
// set the permission (optional).
// if not set it uses the route name:
'permission' => 'login.show|anotherPermission',
// you may specify a custom message to show to the user:
'message' => 'You do not have permission to access the resource!',
// you may specify a message level:
'messageLevel' => 'notice',
// you may specify a route name for redirection:
'redirectRoute' => 'home',
// or you may specify an uri for redirection
'redirectUri' => '/home',
])->name('login.show');
// you may use the middleware alias defined in user config:
$app->route('GET', 'login', function() {
return 'response';
})->middleware('can');
// Run the app:
$app->run();
use Tobento\App\AppFactory;
use Tobento\App\User\Middleware\VerifyRoutePermission;
$app = (new AppFactory())->createApp();
// Add directories:
$app->dirs()
->dir(realpath(__DIR__.'/../'), 'root')
->dir(realpath(__DIR__.'/../app/'), 'app')
->dir($app->dir('app').'config', 'config', group: 'config')
->dir($app->dir('root').'public', 'public')
->dir($app->dir('root').'vendor', 'vendor');
// Adding boots:
$app->boot(\Tobento\App\Http\Boot\Routing::class);
$app->boot(\Tobento\App\User\Boot\User::class);
$app->booting();
// Routes:
$app->routeResource('roles', RolesController::class))
->middleware([
VerifyRoutePermission::class,
'permissions' => [
// 'route.name' => 'permission'
'roles.index' => 'roles',
'roles.show' => 'roles',
'roles.create' => 'roles.create',
'roles.store' => 'roles.create',
'roles.edit' => 'roles.edit',
'roles.update' => 'roles.edit',
'roles.delete' => 'roles.delete',
],
// you may specify a custom message to show to the user:
'message' => 'You do not have permission to access the resource!',
// you may specify a message level:
'messageLevel' => 'notice',
// you may specify a route name for redirection:
'redirectRoute' => 'home',
// or you may specify an uri for redirection
'redirectUri' => '/home',
]);
// Run the app:
$app->run();
use Tobento\App\AppFactory;
use Tobento\App\User\Middleware\VerifyRole;
$app = (new AppFactory())->createApp();
// Add directories:
$app->dirs()
->dir(realpath(__DIR__.'/../'), 'root')
->dir(realpath(__DIR__.'/../app/'), 'app')
->dir($app->dir('app').'config', 'config', group: 'config')
->dir($app->dir('root').'public', 'public')
->dir($app->dir('root').'vendor', 'vendor');
// Adding boots:
$app->boot(\Tobento\App\Http\Boot\Routing::class);
$app->boot(\Tobento\App\User\Boot\User::class);
$app->booting();
// Routes:
$app->route('GET', 'login', function() {
// only for user with role editor and administrator!
return 'response';
})->middleware([
VerifyRole::class,
// set the role.
'role' => 'editor|administrator',
// you may specify a custom message to show to the user:
'message' => 'You do not have a
use Tobento\App\User\Authenticator\IdentityAuthenticator;
use Tobento\App\User\Authenticator\UserVerifiers;
use Tobento\App\User\Authenticator\UserRoleAreaVerifier;
use Tobento\App\User\Authentication\AuthInterface;
use Tobento\App\User\Authentication\Authenticated;
use Tobento\App\User\Authentication\Token\TokenStorageInterface;
use Tobento\App\User\Exception\AuthenticationException;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
class LoginController
{
public function login(
ServerRequestInterface $request,
IdentityAuthenticator $authenticator,
AuthInterface $auth,
TokenStorageInterface $tokenStorage,
): ResponseInterface {
// You may specify the identity attributes to be checked.
// At least one attribute is $user = $authenticator->authenticate($request);
} catch (AuthenticationException $e) {
// handle exception:
// create and return response for exception:
return $createdResponse;
}
// on success create token and start auth:
$token = $tokenStorage->createToken(
payload: ['userId' => $user->id(), 'passwordHash' => $user->password()],
authenticatedVia: 'loginform',
authenticatedBy: $authenticator::class,
// issuedAt: $issuedAt,
// expiresAt: $expiresAt,
);
$auth->start(new Authenticated(token: $token, user: $user));
// create and return response:
return $createdResponse;
}
}
use Tobento\App\User\Authenticator\AttributesAuthenticator;
use Tobento\App\User\Authenticator\UserVerifiers;
use Tobento\App\User\Authenticator\UserRoleAreaVerifier;
use Tobento\App\User\Authentication\AuthInterface;
use Tobento\App\User\Authentication\Authenticated;
use Tobento\App\User\Authentication\Token\TokenStorageInterface;
use Tobento\App\User\Exception\AuthenticationException;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
class LoginController
{
public function login(
ServerRequestInterface $request,
AttributesAuthenticator $authenticator,
AuthInterface $auth,
TokenStorageInterface $tokenStorage,
): ResponseInterface {
// Specify the user attributes to be identified:
$authenticator->addAttribute(
// specify the user attribute name:
name: 'email',
// specify the reuest input name:
// optional, if not set name will be used!
inputName: 'email',
// you may specify the validation rules:
// default rule is create token and start auth:
$token = $tokenStorage->createToken(
payload: ['userId' => $user->id(), 'passwordHash' => $user->password()],
authenticatedVia: 'loginform',
authenticatedBy: $authenticator::class,
// issuedAt: $issuedAt,
// expiresAt: $expiresAt,
);
$auth->start(new Authenticated(token: $token, user: $user));
// create and return response:
return $createdResponse;
// create and return response:
return $createdResponse;
}
}
use Tobento\App\User\Authenticator\UserPermissionVerifier;
// User must have one the specified permission.
$verifier = new UserPermissionVerifier('permission');
use Tobento\App\User\Authenticator\UserRoleVerifier;
// User must have one of the specified role.
$verifier = new UserRoleVerifier('editor', 'author');
use Tobento\App\User\Authenticator\UserRoleAreaVerifier;
// User must have one of the specified role area.
$verifier = new UserRoleAreaVerifier('frontend', 'api');
use Tobento\App\User\Authentication;
use Psr\Container\ContainerInterface;
return [
// ...
'interfaces' => [
// ...
// Default token authenticator:
// Authenticator\TokenAuthenticatorInterface::class => Authenticator\TokenAuthenticator::class,
// Example with token verifiers:
Authenticator\TokenAuthenticatorInterface::class => static function(ContainerInterface $c) {
return new Authenticator\TokenAuthenticator(
verifier: new Authenticator\TokenVerifiers(
new Authenticator\TokenPasswordHashVerifier(
// The token issuers (storage names) to verify password hash.
// If empty it gets verified for all issuers.
issuers: ['session'],
// The attribute name of the payload:
name: 'passwordHash',
),
),
);
},
// ...
],
];
use Tobento\App\User\Authenticator\TokenPasswordHashVerifier;
$verifier = new TokenPasswordHashVerifier(
// The token issuers (storage names) to verify password hash.
// If empty it gets verified for all issuers.
issuers: ['session'],
// Will only be verified if authenticated
// via remembered or loginlink if specified:
authenticatedVia: 'remembered|loginlink',
// The attribute name of the payload:
name: 'passwordHash',
);
use Tobento\App\User\Authenticator\TokenPayloadVerifier;
$verifier = new TokenPayloadVerifier(
// Specify the payload attribute name:
name: 'remoteAddress',
// Specify the value to match:
value: $_SERVER['REMOTE_ADDR'] ?? null,
// The token issuers (storage names) to verify password hash.
// If empty it gets verified for all issuers.
issuers: ['session'],
// Will only be verified if authenticated
// via remembered or loginlink if specified:
authenticatedVia: 'remembered|loginlink',
);
use Tobento\App\User\Authentication;
use Psr\Container\ContainerInterface;
return [
// ...
'interfaces' => [
// ...
// Define the token storages you wish to support:
Authentication\Token\TokenStoragesInterface::class => static function(ContainerInterface $c) {
return new Authentication\Token\TokenStorages(
// add null storage:
new Authentication\Token\NullStorage(),
);
},
// Define the default token storage used for auth:
Authentication\Token\TokenStorageInterface::class => static function(ContainerInterface $c) {
// you might change to null:
return $c->get(Authentication\Token\TokenStoragesInterface::class)->get('null');
},
// ...
],
];
use Tobento\App\User\Authentication;
use Psr\Container\ContainerInterface;
use Psr\Clock\ClockInterface;
return [
// ...
'interfaces' => [
// ...
// Define the token storages you wish to support:
Authentication\Token\TokenStoragesInterface::class => static function(ContainerInterface $c) {
return new Authentication\Token\TokenStorages(
// add inmemory storage:
new Authentication\Token\InMemoryStorage(
clock: $c->get(ClockInterface::class),
),
);
},
// Define the default token storage used for auth:
Authentication\Token\TokenStorageInterface::class => static function(ContainerInterface $c) {
// you might change to inmemory:
return $c->get(Authentication\Token\TokenStoragesInterface::class)->get('inmemory');
},
// ...
],
];
use Tobento\App\User\Authentication;
use Tobento\Service\Storage\StorageInterface;
use Psr\Container\ContainerInterface;
use Psr\Clock\ClockInterface;
return [
// ...
'interfaces' => [
// ...
// Define the token storages you wish to support:
Authentication\Token\TokenStoragesInterface::class => static function(ContainerInterface $c) {
return new Authentication\Token\TokenStorages(
new Authentication\Token\RepositoryStorage(
clock: $c->get(ClockInterface::class),
repository: new Authentication\Token\TokenRepository(
storage: $c->get(StorageInterface::class)->new(),
table: 'auth_tokens',
),
name: 'repository',
),
);
},
// Define the default token storage used for auth:
Authentication\Token\TokenStorageInterface::class => static function(ContainerInterface $c) {
return $c->get(Authentication\Token\TokenStoragesInterface::class)->get('repository');
},
// ...
],
];
$repositoryStorage->deleteExpiredTokens();
use Tobento\App\User\Authentication;
use Tobento\Service\Session\SessionInterface;
use Psr\Container\ContainerInterface;
use Psr\Clock\ClockInterface;
return [
// ...
'interfaces' => [
// ...
// Define the token storages you wish to support:
Authentication\Token\TokenStoragesInterface::class => static function(ContainerInterface $c) {
return new Authentication\Token\TokenStorages(
// add session storage:
new Authentication\Token\SessionStorage(
session: $c->get(SessionInterface::class),
clock: $c->get(ClockInterface::class),
),
);
},
// Define the default token storage used for auth:
Authentication\Token\TokenStorageInterface::class => static function(ContainerInterface $c) {
// you might change to session:
return $c->get(Authentication\Token\TokenStoragesInterface::class)->get('session');
},
// ...
],
];
use Tobento\App\AppFactory;
// Create the app
$app = (new AppFactory())->createApp();
// Adding boots
$app->boot(\Tobento\App\User\Boot\User::class);
$app->boot(\Tobento\App\Http\Boot\Session::class);
// Run the app
$app->run();
use Tobento\App\User\Authentication;
use Psr\Container\ContainerInterface;
use Psr\Clock\ClockInterface;
return [
// ...
'interfaces' => [
// ...
// Define the token transport you wish to support:
Authentication\Token\TokenTransportsInterface::class => static function(ContainerInterface $c) {
return new Authentication\Token\TokenTransports(
new Authentication\Token\CookieTransport(
clock: $c->get(ClockInterface::class),
cookieName: 'token',
),
);
},
// Define the default token transport(s) used for auth:
Authentication\Token\TokenTransportInterface::class => static function(ContainerInterface $c) {
return $c->get(Authentication\Token\TokenTransportsInterface::class)->get('cookie');
//return $c->get(Authentication\Token\TokenTransportsInterface::class); // all
//return $c->get(Authentication\Token\TokenTransportsInterface::class)->only(['cookie']);
},
// ...
],
];
use Tobento\App\AppFactory;
// Create the app
$app = (new AppFactory())->createApp();
// Adding boots
$app->boot(\Tobento\App\User\Boot\User::class);
$app->boot(\Tobento\App\Http\Boot\Cookies::class);
// Run the app
$app->run();
use Tobento\App\User\Authentication;
use Psr\Container\ContainerInterface;
return [
// ...
'interfaces' => [
// ...
// Define the token transport you wish to support:
Authentication\Token\TokenTransportsInterface::class => static function(ContainerInterface $c) {
return new Authentication\Token\TokenTransports(
new Authentication\Token\HeaderTransport(name: 'header', headerName: 'X-Auth-Token'),
);
},
// Define the default token transport(s) used for auth:
Authentication\Token\TokenTransportInterface::class => static function(ContainerInterface $c) {
return $c->get(Authentication\Token\TokenTransportsInterface::class)->get('header');
//return $c->get(Authentication\Token\TokenTransportsInterface::class); // all
//return $c->get(Authentication\Token\TokenTransportsInterface::class)->only(['header']);
},
// ...
],
];
use Tobento\App\User\Event;
use Tobento\App\User\Migration\RolePermissionsAction;
use Tobento\App\User\RoleRepositoryInterface;
use Tobento\Service\Migration\MigrationInterface;
use Tobento\Service\Migration\ActionsInterface;
use Tobento\Service\Migration\Actions;
class RolesPermissionMigration implements MigrationInterface
{
public function __construct(
protected RoleRepositoryInterface $roleRepository,
) {}
/**
* Return a description of the migration.
*
* @return string
*/
public function description(): string
{
return 'Role permissions.';
}
/**
* Return the actions to be processed on install.
*
* @return ActionsInterface
*/
public function install(): ActionsInterface
{
return new Actions(
new RolePermissionsAction(
roleRepository: $this->roleRepository,
add: [
'developer' => ['roles', 'roles.create', 'roles.edit', 'roles.delete', 'roles.permissions'],
'administrator' => ['roles', 'roles.create', 'roles.edit', 'roles.delete', 'roles.permissions'],
],
description: 'Roles permissions added for developer and administrator',
),
);
}
/**
* Return the actions to be processed on uninstall.
*
* @return ActionsInterface
*/
public function uninstall(): ActionsInterface
{
return new Actions(
new RolePermissionsAction(
roleRepository: $this->roleRepository,
remove: [
'developer' => ['roles', 'roles.create', 'roles.edit', 'roles.delete', 'roles.permissions'],
'administrator' => ['roles', 'roles.create', 'roles.edit', 'roles.delete', 'roles.permissions'],
],
description: 'Roles permissions removed for developer and administrator',
),
);
}
}
use Tobento\App\User\Authentication;
use Psr\Container\ContainerInterface;
use Psr\Clock\ClockInterface;
return [
// ...
'middlewares' => [
// Uncomment it and set it on each route individually!
// User\Middleware\Authentication::class,
],
'interfaces' => [
// ...
// Define the token storages you wish to support:
Authentication\Token\TokenStoragesInterface::class => static function(ContainerInterface $c) {
return new Authentication\Token\TokenStorages(
new Authentication\Token\SessionStorage(
session: $c->get(SessionInterface::class),
clock: $c->get(ClockInterface::class),
),
);
},
// Define the token transport you wish to support:
Authentication\Token\TokenTransportsInterface::class => static function(ContainerInterface $c) {
return new Authentication\Token\TokenTransports(
new Authentication\Token\CookieTransport(
clock: $c->get(ClockInterface::class),
cookieName: 'token',
),
new Authentication\Token\HeaderTransport(name: 'header', headerName: 'X-Auth-Token'),
);
},
// ...
],
];
use Tobento\App\User\Middleware\AuthenticationWith;
use Tobento\Service\Routing\RouteGroupInterface;
// ...
// Routes:
// Web example:
$app->routeGroup('', function(RouteGroupInterface $group) {
// define your web routes:
})->middleware([
AuthenticationWith::class,
// specify the token transport name:
'transportName' => 'cookie',
// specify the token storage name:
'storageName' => 'session',
]);
// Api example:
$app->routeGroup('api', function(RouteGroupInterface $group) {
// define your api routes:
})->middleware([
AuthenticationWith::class,
// specify the token transport name:
'transportName' => 'header',
// specify the token storage name:
'storageName' => 'session',
]);
// ...
use Tobento\App\User\PasswordHasherInterface;
class SomeService
{
public function __construct(
private PasswordHasherInterface $passwordHasher,
) {
// hash password:
$hashedPassword = $passwordHasher->hash(plainPassword: 'password');
// verify password:
$isValid = $passwordHasher->verify(hashedPassword: $hashedPassword, plainPassword: 'password');
}
}
use Tobento\App\User\UserRepositoryInterface;
use DateTime;
class SomeService
{
public function __construct(
private UserRepositoryInterface $userRepository,
) {
$updatedUser = $userRepository->addVerified(
id: 5, // user id
channel: 'email',
verifiedAt: new DateTime('2023-09-24 00:00:00'),
);
}
}
use Tobento\App\User\UserRepositoryInterface;
use DateTime;
class SomeService
{
public function __construct(
private UserRepositoryInterface $userRepository,
) {
$updatedUser = $userRepository->removeVerified(
id: 5, // user id
channel: 'email',
);
}
}
use Tobento\App\User\UserInterface;
var_dump($user instanceof UserInterface);
// bool(true)
// Get the verified channels:
$verified = $user->getVerified();
// ['email' => '2023-09-24 00:00:00']
// Get the date verified at for a specific channel:
$emailVerifiedAt = $user->getVerifiedAt(channel: 'email');
// '2023-09-24 00:00:00' or NULL
// Returns true if the specified channels are verified, otherwise false.
$verified = $user->isVerified(channels: ['email', 'smartphone']);
// Returns true if at least one channel is verified, otherwise false.
$verified = $user->isOneVerified();
// or one of the specified channels:
$verified = $user->isOneVerified(channels: ['email', 'smartphone']);
app/config/user.php
app/config/user.php
app/config/database.php
app/config/user.php
app/config/user.php
app/config/user.php
app/config/user.php
app/config/user.php
app/config/user.php
app/config/user.php
app/config/user.php
app/config/user.php
app/config/user.php
app/config/user.php
app/config/user.php
php ap acl:roles
php ap acl:rules
php ap auth:purge-tokens
php ap auth:purge-tokens --storage=name
app/config/user.php
app/config/user.php
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.