Asynchroniczne logowanie - kpiorun/symfony2 GitHub Wiki
Założenia:
- Rozwiązanie musi używać obecny w Symfony2 komponent Security.
- Rozwiązanie musi logować użytkownika dokładnie z użyciem tego samego url-a, standardowo jest to /login_check, ale w przypadku gdy jest to zapytanie ajax-owe powinno zwrócić w odpowiedzi poprawną odpowiedź w formacie JSON.
- Odpowiedź powinna być równa: { result: true; } gdy użytkownik podał poprawne dane, lub { result: false; } w przeciwnym przypadku.
W celu wykorzystania komponentu Security zmienione zostały ustawienia form_login w pliku app/config/Security Należy przechwycić zdarzenie success lub failure rezygnując z defaultowej ścieżki.
`# app/config/security.yml
security:
encoders:
FOS\UserBundle\Model\UserInterface: sha512
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
providers:
fos_userbundle:
id: fos_user.user_provider.username
firewalls:
main:
pattern: ^/
form_login:
provider: fos_userbundle
#csrf_provider: form.csrf_provider
#default_target_path: /generuj-kod
use_referer: false
failure_handler: authentication_handler
success_handler: authentication_handler
remember_me:
lifetime: 604800
key: 3aafe9fde8cc6ec0d6e25e5bc2d143b3
logout: true
anonymous: true
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/, role: ROLE_ADMIN }`
Plik Piorun/HomeSiteBundle/Reources/config/services.yml
`services:
authentication_handler:
class: 'FOS\UserBundle\Handler\AuthenticationHandler'
arguments: ["@service_container"]`
Stworzony został Handler sprawdzający czy przesłane zapytanie jest Ajaxowe. Jeżeli tak to odpowiednio dla przypadku niepowodzenia zwraca false dla poprawnego true.
`<?php
namespace FOS\UserBundle\Handler;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
class AuthenticationHandler implements AuthenticationSuccessHandlerInterface, AuthenticationFailureHandlerInterface
{
public function __construct(Container $container)
{
$this->container = $container;
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
if ($request->isXmlHttpRequest()) {
return new JsonResponse(array('result' => false));
}
$request->getSession()->set(SecurityContextInterface::AUTHENTICATION_ERROR, $exception);
$url = $request->headers->get('referer');
return new RedirectResponse($url);
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token)
{
if ($request->isXmlHttpRequest()) {
return new JsonResponse(array('result' => true));
}
$key = '_security.main.target_path';
if ($this->container->get('session')->has($key)) {
$url = $this->container->get('session')->get($key);
} else {
$url = $this->container->get('router')->generate('piorun_home_site_adminpage');
}
return new RedirectResponse($url);
}
}`
Wywołanie metody logowania asynchronicznego może być następujące
`var data = {'_username':'administrator','_password':'1111' };
$.ajax({
type: "POST",
url:'http://path/web/app_dev.php/login_check' ,
data:data,
});`