Download the PHP package locksyk/api-session-bundle without Composer

On this page you can find all versions of the php package locksyk/api-session-bundle. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package api-session-bundle

ApiSessionBundle

Stateful Symfony firewalls for API endpoints: the session id travels in the Authorization: Bearer header instead of a cookie.

Status: published. Available on Packagist as locksyk/api-session-bundle; feature-complete against its design (DESIGN.md) and fully tested. Pre-1.0: minor releases may still adjust the API.

Why

Stateless token schemes (JWT & friends) give up what server-side sessions provide for free: instant revocation, server-side state, idle expiry, no claims-refresh problem. This bundle keeps Symfony's ordinary session machinery - it just moves the session id out of the cookie and into a bearer token:

Requirements: PHP >= 8.2, Symfony 6.4 LTS, 7.x or 8.x (Symfony 8 requires PHP >= 8.4).

Installation

Enable the bundle (Flex does this automatically):

Quick start

Keep your firewall exactly as it would be for cookie sessions - any authenticator works (json_login, WebAuthn, OIDC, custom):

Then bridge it:

Optionally mount the ready-made login responder (the authenticator still handles credentials; this shapes the success response):

That's it. Log in and the response carries the session token in the X-Session-Token header (and, with LoginController, in the body as {user, roles, token}); present it on every request:

The client contract

A ready-made browser implementation, @locksyk/api-session-client, lives in frontend/ - a dependency-free TypeScript module with a drop-in fetch wrapper. The rules it implements:

Pre-authentication flows work naturally: e.g. a WebAuthn ceremony calls POST /api/auth/options (server stores the challenge in a fresh anonymous session -> response carries its token), then presents that token on POST /api/auth/verify; the login success response carries the rotated, authenticated token.

Configuration reference

Token format

The default strategy signs the claims with HMAC-SHA256, keyed by a derivation of kernel.secret (rotating the secret invalidates all outstanding tokens):

The MAC covers the expiry, so clients may read it (to refresh proactively) but cannot alter it. A leaked session-store key is not a usable credential - building a token requires the app secret.

Absolute lifetime and refresh

By default tokens live as long as their session (sliding idle expiry). Setting token.lifetime embeds a signed absolute expiry in every minted token, enforced before the session is ever touched. Mount the refresh endpoint to let clients extend their stay:

POST /api/refresh with a valid token returns {token, expires_in} - an additional token for the same session with a fresh expiry. Notes:

Logout

Symfony's plain logout: firewall config works as-is - the session is invalidated, so every token for it dies instantly, and no stray cookie headers leak. logout.json_response: true answers 204 No Content instead of the default redirect; your own LogoutEvent listeners can still replace the response.

Impersonation (switch-user)

Do not enable Symfony's switch_user firewall option. Mount the endpoints instead - nothing impersonation-related exists unless you do:

POST with {"identifier": "<user>"} enters impersonation (requires switch_user.role; the impersonation token carries the target's roles, and IS_IMPERSONATOR and friends behave as usual); DELETE exits. Responses: 400 bad body, 403 missing role or listener veto, 404 unknown target, 409 already/not impersonating.

The token also carries ROLE_PREVIOUS_ADMIN on Symfony 6.4 only, matching what that version's built-in switch_user did. Symfony 7.0 dropped the convention on both sides at once - SwitchUserListener stopped granting the role, and ContextListener stopped expecting it - so on 7.0+ the role must be absent or the token's roles no longer match the reloaded user's and the session is deauthenticated on the next request. Check IS_IMPERSONATOR rather than the role in your own voters; it works on every supported version.

The default grant_previous_admin_role: auto reads http-kernel's version as a stand-in for security-http's, which is right for any install that keeps its Symfony components on one major. Set it to true or false if yours does not - security-http 6.4 with http-kernel ^7.0 is the pairing auto gets wrong (it needs true). The symptom of a wrong value is impersonation that returns 200 and then 401s on every request after it.

Guard listeners subscribe to the bundle's ImpersonationEnteredEvent / ImpersonationExitedEvent - each fires only for its direction, so no request-parameter sniffing - and veto by throwing AccessDeniedException. Symfony's SwitchUserEvent is also dispatched for existing listeners. The target is resolved through your user provider (the autowiring alias when exactly one is configured; multi-provider apps rebind the controller's provider argument).

Exiting dispatches a pair of events, because it is two pieces of work under two identities. ImpersonationExitedEvent fires while the impersonation token is still in place - the current user is the one being put down, so this is where work about the borrowed identity goes. ImpersonatorResumedEvent fires once the original token is back, for work about the impersonator; a listener there can ask the token storage who is acting and get the right answer.

To end an impersonation without waiting to be asked - a deadline of your own having passed, say - inject ImpersonationManager:

It returns the user now acting again, or null if nothing was being impersonated, and produces the same events in the same order as the endpoint. A forced exit cannot be vetoed: AccessDeniedException from a listener stands only for a requested exit, and listeners that guard exits should check $event->isVetoable() before throwing.

Stale-token signalling

When a presented token verifies as ours but is no longer usable, three signals fire:

CSRF

Bearer-carried sessions have no ambient credential, so classic CSRF does not apply; by default the bundle bypasses CSRF validation on bridged firewalls (form-login, logout, and app-level checks alike) while leaving the rest of the app untouched. Set csrf_bypass: false to keep validation.

Custom token strategies

Alias LocksyK\ApiSessionBundle\Token\TokenStrategyInterface to your own service to change the token encoding - e.g. authenticated encryption that hides the session id from the client entirely:

Security contract: every claim - session id and expiry - must be integrity-protected. The bridge enforces expiry from the decoded claims alone; an encoding that lets a client alter them without detection is exploitable by construction, and that responsibility sits with the implementation. Strategies must be able to mint for any session id the session layer chooses (non-invertible mappings are unsupported).

Enhancement patterns: revocation

Two events form the extension surface for stricter token semantics:

Reference implementations (copy them from the test suite; the stamped fields are ordinary app-owned session data):

Testing your app against the bundle

BrowserKit's loginUser() does not work on a bridged firewall - it plants a session cookie, which the bridge deliberately ignores, so API requests stay unauthenticated with no error to point at the cause. Functional tests must log in through the real path instead, so the token contract (authenticator -> session migration -> token advertisement) is exercised rather than bypassed.

The bundle ships a ready-made authenticator for exactly that: LocksyK\ApiSessionBundle\Test\TestLoginAuthenticator answers POST /api/test/login with {"email": "<identifier>"} and logs that user in through the full stack. It is not registered by the bundle's DI - it is test-only tooling, and your app wires it up itself (it refuses to run unless the kernel environment is test, and the route only exists there anyway). Three snippets:

A test then logs in and captures the advertised token:

The constructor optionally takes the path, the environment name the authenticator is active in (default test), and the JSON key holding the user identifier (default email).

License

GNU General Public License, version 2 only (GPL-2.0-only). See LICENSE.


All versions of api-session-bundle with dependencies

PHP Build Version
Package Version
Requires php Version >=8.2
psr/log Version ^1.1 || ^2.0 || ^3.0
symfony/config Version ^6.4 || ^7.0 || ^8.0
symfony/dependency-injection Version ^6.4 || ^7.0 || ^8.0
symfony/event-dispatcher Version ^6.4 || ^7.0 || ^8.0
symfony/event-dispatcher-contracts Version ^2.5 || ^3.0
symfony/http-foundation Version ^6.4 || ^7.0 || ^8.0
symfony/http-kernel Version ^6.4 || ^7.0 || ^8.0
symfony/security-bundle Version ^6.4 || ^7.0 || ^8.0
symfony/security-core Version ^6.4 || ^7.0 || ^8.0
symfony/security-http Version ^6.4 || ^7.0 || ^8.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package locksyk/api-session-bundle contains the following files

Loading the files please wait ...