xphere/one-time-access-bundle
Do you ever wanted to authenticate your users in a Symfony2 application through a one-time access url?, (*1)
Seek no more! This is your bundle! :D, (*2)
, (*3)
⚠ Note ⚠
Mind the package rename
- Before 1.0.0
: berny/one-time-access-bundle
- After 1.0.0
: xphere/one-time-access-bundle
, (*4)
Why I would want that?
You can use one-time access urls for:
- Access to "Forgot your password?" forms
- Password-less systems, (*5)
Features
- Customizable urls
- User defined token generation and retrieval
- Multiple firewalls
Compatibility
Tested under Symfony2 2.1.1 and greater, (*6)
Installation
- Add
"xphere/one-time-access-bundle": "^1.1"
to your composer.json
file
- Add the bundle to your kernel with
new xPheRe\OneTimeAccessBundle\xPheReOneTimeAccessBundle()
Usage
Add a one_time_access
key in any firewall with, at least, a route
., (*7)
security:
firewalls:
root:
one_time_access:
route: acme_myapp_ota
The current user provider must implement OneTimeAccessBundle\Security\Provider\ProviderInterface
., (*8)
security:
provider:
users:
entity:
# AcmeMyAppBundle:UserRepository implements ProviderInterface
class: AcmeMyAppBundle:User
firewalls:
root:
provider: users
one_time_access:
route: acme_myapp_ota
You can set the ota_provider
key to define a different service implementing the interface., (*9)
services:
acme.myapp.ota.repository:
class: Acme\\MyAppSecurity\\UserProvider
security:
firewalls:
root:
one_time_access:
route: acme_myapp_ota
ota_provider: acme.myapp.ota.repository
By default, route
must have a _token
parameter to extract the one-time access token., (*10)
acme_myapp_ota:
pattern: ^/autologin/{_token}
defaults: { _controller: AcmeMyAppBundle:Login:oneTimeAccess }
This can be customized with the parameter
key., (*11)
security:
firewalls:
root:
one_time_access:
route: acme_myapp_ota
parameter: otatoken
Of course, you can define your routes as always, using YAML, XML, annotations... you name it., (*12)
Token generation
This bundle doesn't cover token generation.
It's up to you to create unique tokens and link them to the user., (*13)
This could be part of a Doctrine implementation:, (*14)
class OTARepository extends EntityRepository implements ProviderInterface
{
public function generateOTA($user)
{
$token = md5($user->getUsername() . time());
$ota = new YourOneTimeAccessEntity($user, $token);
$this->getEntityManager()->persist($ota);
$this->getEntityManager()->flush($ota);
return $ota;
}
public function loadUserByOTA($token)
{
$ota = $this->findOneByToken($token);
if ($ota) {
// Remember, user must be defined as EAGER in OTAEntity
return $ota->getUser();
}
}
public function invalidateByOTA($token)
{
$ota = $this->findOneByToken($token);
$this->getEntityManager()->remove($ota);
$this->getEntityManager()->flush();
}
}
Route generation
Route generation is up to you too. Yes!
Are we being lazy, you say? Nope!
This means FULLY CUSTOMIZABLE routes for your one-time access links., (*15)
For example:, (*16)
$ota = $oneTimeAccessRepository->generateOnetimeAccess($user);
$url = $this->generateUrl('acme_myapp_ota', array(
'_token' => $ota->getToken(),
));