Session
in package
Per-`AxiamClient` session state (CONTRACT.md §3/§4/§5/§9): owns the shared Guzzle `CookieJar` (§4), captures/exposes the non-browser CSRF token (§3), and is the single-flight home for the shared refresh `Promise` (§9, D-06).
tenant is a required constructor parameter with no nullable default (D-13) — there
is no default-tenant fallback anywhere in this class or in any of its callers.
refreshIfNeeded() returns the SAME PromiseInterface to every concurrent caller
until it settles. The check-and-store below (the null check immediately followed
by the assignment) executes synchronously — nothing in between calls ->wait() or
yields — so it is safe without a mutex even under N concurrent async callers sharing
one Session instance (D-06's "fiber-safe by construction" claim; PHP Fibers are
cooperative/non-preemptive, and Guzzle's own promise resolution never interleaves
mid-statement).
The $http client passed in is used directly for the refresh POST. In production
wiring (a later plan assembles AxiamClient), that client is expected to be
constructed WITHOUT RefreshMiddleware attached, so a 401 response to the refresh
call itself can never recursively re-enter the single-flight guard; this plan does
not need to solve that wiring, only provide the guard itself.
Table of Contents
Methods
- __construct() : mixed
- accessToken() : string|null
- The current access token, read live from the shared cookie jar's `axiam_access` entry rather than cached separately — avoids a second, potentially-stale, copy of the token (mirrors the Java SDK's `SessionState::cachedAccessToken()` and the Go SDK's `cookieValue()` helper).
- baseUrl() : string
- AXIAM server base URL this session is bound to.
- cookieJar() : CookieJar
- §4: the single cookie jar every REST-facing Guzzle client MUST share.
- csrfToken() : string|null
- §3 non-browser CSRF: the most recently captured `X-CSRF-Token` response header.
- refreshIfNeeded() : PromiseInterface
- Returns the SAME `PromiseInterface` to every caller until it resolves (SC#2, D-06). On success: captures the `X-CSRF-Token` response header, then clears the stored promise. On failure: clears the stored promise and rejects with `AuthError` — no retry loop (§9.3). Clear-on-both-paths bookkeeping and the failure-to-`AuthError` translation are factored into {@see RefreshGuard::settle()} so REST and (later) gRPC never re-implement — or drift on — that one mechanism; {@see RefreshGuard::settle()}'s `$onClear` closure below is invoked on EITHER outcome, never on both, never on neither.
- resetCsrf() : void
- Clears the captured CSRF token — called by {@see \Axiam\Sdk\AxiamClient::logout()} so a logged-out session never echoes a stale `X-CSRF-Token` on a subsequent (re-authenticated) request. Purely additive: does not change {@see self::csrfToken()}'s or {@see self::refreshIfNeeded()}'s existing behavior in any other way.
- tenant() : string
- Tenant slug every request in this session is scoped to.
Methods
__construct()
public
__construct(string $baseUrl, string $tenant, Client $http[, CookieJar|null $cookieJar = null ]) : mixed
Parameters
- $baseUrl : string
-
AXIAM server base URL (HTTPS;
http://is rejected except on loopback). - $tenant : string
-
Tenant slug every request is scoped to.
- $http : Client
-
Guzzle client carrying this session's middleware stack.
- $cookieJar : CookieJar|null = null
-
Persistent cookie store (CONTRACT.md §4). Defaults to a fresh in-memory jar — REQUIRED, because AXIAM delivers the access and refresh tokens as
httpOnlycookies, so a client that does not persist them fails every request after login.
accessToken()
The current access token, read live from the shared cookie jar's `axiam_access` entry rather than cached separately — avoids a second, potentially-stale, copy of the token (mirrors the Java SDK's `SessionState::cachedAccessToken()` and the Go SDK's `cookieValue()` helper).
public
accessToken() : string|null
Return values
string|nullbaseUrl()
AXIAM server base URL this session is bound to.
public
baseUrl() : string
Return values
stringcookieJar()
§4: the single cookie jar every REST-facing Guzzle client MUST share.
public
cookieJar() : CookieJar
Return values
CookieJarcsrfToken()
§3 non-browser CSRF: the most recently captured `X-CSRF-Token` response header.
public
csrfToken() : string|null
Return values
string|nullrefreshIfNeeded()
Returns the SAME `PromiseInterface` to every caller until it resolves (SC#2, D-06). On success: captures the `X-CSRF-Token` response header, then clears the stored promise. On failure: clears the stored promise and rejects with `AuthError` — no retry loop (§9.3). Clear-on-both-paths bookkeeping and the failure-to-`AuthError` translation are factored into {@see RefreshGuard::settle()} so REST and (later) gRPC never re-implement — or drift on — that one mechanism; {@see RefreshGuard::settle()}'s `$onClear` closure below is invoked on EITHER outcome, never on both, never on neither.
public
refreshIfNeeded() : PromiseInterface
Return values
PromiseInterfaceresetCsrf()
Clears the captured CSRF token — called by {@see \Axiam\Sdk\AxiamClient::logout()} so a logged-out session never echoes a stale `X-CSRF-Token` on a subsequent (re-authenticated) request. Purely additive: does not change {@see self::csrfToken()}'s or {@see self::refreshIfNeeded()}'s existing behavior in any other way.
public
resetCsrf() : void
tenant()
Tenant slug every request in this session is scoped to.
public
tenant() : string