Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Ajax Fos User Bundle Laravel Package

tecnocreaciones/ajax-fos-user-bundle

Tecnocreaciones AjaxFOSUserBundle is a Symfony bundle that adds AJAX support to FOSUserBundle, enabling asynchronous user registration, login, and profile actions without full page reloads. It provides routes, controllers, and templates for smoother user flows.

View on GitHub
Deep Wiki
Context7

Getting Started

First, calibrate expectations: this is a Symfony 2.x/3.x bundle for FOSUserBundle, not a Laravel package. Its whole job is to make FOSUserBundle's form login return JSON instead of a 302 redirect when the request is an XMLHttpRequest. If you are working in a Laravel codebase, the equivalent is Fortify/Sanctum with a custom LoginResponse — there is nothing here to install. If you are on a legacy Symfony app, read on.

Minimal steps:

  1. Install FOSUserBundle and get a normal, working server-rendered login first. This bundle is an adapter layer; it cannot fix a broken firewall.
  2. composer require tecnocreaciones/ajax-fos-user-bundle. The single tagged release is from 2017, so on anything newer than Symfony 3.4 you will likely need :dev-master and may hit PHP 7.1+ / Symfony\Component\Security\Core\Authentication\Token\TokenInterface signature issues.
  3. Register new Tecnocreaciones\AjaxFOSUserBundle\AjaxFOSUserBundle() in app/AppKernel.php.
  4. Look first at the bundle source, not the README (the README is thin):
    • Resources/config/services.xml — the authoritative list of service IDs and tags. Everything you wire in security.yml must match these.
    • Security/Authentication/Handler/ — the success and failure handlers that build the JSON payloads.
    • DependencyInjection/ — what is actually configurable.
  5. First use case: POST /login_check with _username, _password, _csrf_token, and X-Requested-With: XMLHttpRequest, receive 200 {"success":true,...} or 401 {"success":false,"message":"..."} instead of a redirect.

Implementation Patterns

Firewall wiring. Do not replace form_login; decorate it. Point success_handler and failure_handler at the bundle's services inside your existing firewall:

firewalls:
    main:
        form_login:
            login_path: /login
            check_path: /login_check
            success_handler: tecnocreaciones.ajax_fos_user.handler.success   # verify ID in services.xml
            failure_handler: tecnocreaciones.ajax_fos_user.handler.failure
        anonymous: ~
        remember_me: { secret: "%secret%" }

If the bundle ships a request listener that auto-detects AJAX, leave it tagged as-is and use the handlers only as a fallback for non-AJAX clients.

CSRF token bootstrap. The most common frontend pattern is a two-request flow: GET /login (or a tiny controller that renders the token) to scrape _csrf_token from the form, then POST /login_check with it. Cache the token in memory; do not fetch it on every keystroke.

Client wrapper. Centralize the call rather than scattering $.ajax:

async function login(username, password, csrf) {
  const res = await fetch('/login_check', {
    method: 'POST',
    credentials: 'include',                    // session cookie must round-trip
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
      'X-Requested-With': 'XMLHttpRequest',    // this header is the whole trigger
    },
    body: new URLSearchParams({ _username: username, _password: password, _csrf_token: csrf }),
  });
  return { ok: res.ok, data: await res.json().catch(() => ({})) };
}

Add a "whoami" endpoint. FOSUserBundle predates SPAs and has no JSON identity endpoint. Write a five-line controller returning $this->getUser() serialized, guarded by @Security("is_granted('IS_AUTHENTICATED_FULLY')"). Your frontend needs it to rehydrate after a page refresh.

Registration and password reset. This bundle does not cover them. The repeatable pattern is a thin controller that calls $form->handleRequest($request) and, when $form->isValid() is false, returns JsonResponse(['errors' => ...]) built from $form->getErrors(true). Return 400, not 200, so clients can branch on status.

Functional tests. Send the AJAX header in your test client; otherwise you are testing the redirect path and will get green tests that do not exercise the code you care about:

$client->request('POST', '/login_check', [...], [], ['HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest']);
$this->assertJsonResponse($client->getResponse(), 200);

Gotchas and Tips

  • It is effectively abandoned. Last release 2017-03-28, 9 stars, zero dependents. Treat every dependency bump as a potential breakage. Pin the exact version in composer.json and commit composer.lock.
  • The AJAX detection header is the #1 failure. Vanilla fetch and most axios configs do not send X-Requested-With. Without it you silently get a 302 and HTML — which looks like "the bundle is broken" when it just was not consulted.
  • CORS + credentials. Cross-origin SPAs must use credentials: 'include' and the server must return an explicit Access-Control-Allow-Origin (never *) plus Access-Control-Allow-Credentials: true. The success handler still rotates the session and may set a remember-me cookie; if Set-Cookie does not reach the browser, login "succeeds" and the next request is anonymous.
  • CSRF field names differ across FOSUserBundle versions (_csrf_token vs _csrf_login). Read the generated HTML once and copy the name exactly.
  • Leaking exception messages. Failure handlers typically serialize getMessage(). BadCredentialsException vs UsernameNotFoundException is a user-enumeration vector — override the handler in prod to return a generic message.
  • Extend, do not fork. Subclass the success/failure handler, register it as your own service, and reference that in security.yml. This keeps your custom payload (extra user fields, redirect URL, flash messages) out of vendor/.
  • Debugging: tail the security log channel at INFO; the firewall decision (AuthenticationException vs AccessDeniedException vs nothing at all) tells you instantly whether the listener ran. If you see the redirect handler in play, the header or the firewall check_path is wrong.
  • Migration path, and the honest recommendation: Symfony 4.4+ ships json_login natively (security.yaml → firewalls.main.json_login.check_path). It does exactly what this bundle does, is maintained, and requires no third-party code. For any app you are not forced to keep on Symfony 2/3, plan to delete this bundle and switch to json_login; budget it as a half-day refactor, not a rewrite.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin