The RefreshTokens facade
RoundlyConsulting\RefreshTokens\Facades\RefreshTokens (alias RefreshTokens) is the recommended entry point. Token verbs sit flat on the facade; everything about one owner’s sessions hangs off sessions($owner), and one row you already hold off session($row):
use RoundlyConsulting\RefreshTokens\Facades\RefreshTokens;
RefreshTokens::for($user)->fromRequest($request)->linkedTo($jti)->issue(); // fluent issue
RefreshTokens::issue($user, new IssueContext(/* … */)); // the same, as a DTO
RefreshTokens::redeem($plain, ownerType: $morph); // ?RedemptionResult
RefreshTokens::rotate($plain, new RotationContext(/* … */)); // ?RotationResult
RefreshTokens::revoke($plain); // bool — logout with the token in hand
RefreshTokens::prune(days: 7); // int — force-delete dead rows
RefreshTokens::sessions($user)->all(); // active sessions, newest first
RefreshTokens::sessions($user)->find($familyId); // ?RefreshToken
RefreshTokens::sessions($user)->revoke($familyId, RevocationReason::Logout); // bool
RefreshTokens::sessions($user)->revokeOthers($currentJti); // int
RefreshTokens::sessions($user)->revokeAllExcept($keepFamilyId); // int
RefreshTokens::sessions($user)->revokeAll(); // int
RefreshTokens::session($row)->enrich($device, $location); // row model or its key
RefreshTokens::session($row)->revoke(RevocationReason::Manual); // boolMethod reference
| Method | Returns | What it does |
|---|---|---|
for($owner) | PendingIssue | Fluent issue builder; ->issue() calls issue(). |
issue($owner, IssueContext $context) | NewRefreshToken | Issue a token; the plaintext is returned once. |
redeem($plain, ?string $ownerType = null) | ?RedemptionResult | Atomically claim a token; every failure is null. |
rotate($plain, ?RotationContext $context = null) | ?RotationResult | Redeem and issue a same-family replacement in one call. |
revoke($plain, $reason = Logout) | bool | Logout with the token in hand; true when it ended a live session. A spent token ends the session it was rotated into. |
sessions($owner) | OwnerSessions | One owner’s sessions — list, find and revoke by family id. |
session($row) | SessionHandle | One row (the model or its key) — enrich or revoke it. |
prune(?int $days = null) | int | Force-delete dead rows; returns the count deleted. |
fake() | RefreshTokensFake | Swap in the recording fake — see Testing. |
The sessions() and session() handles
| Method | Returns | Notes |
|---|---|---|
sessions($owner)->all() | Collection<RefreshToken> | Active rows, newest first. |
sessions($owner)->find($familyId) | ?RefreshToken | The active row of that family; null for a malformed id or another owner’s family. |
sessions($owner)->revoke($familyId, $reason) | bool | Revokes every active row of the family (default Logout); false when nothing was active. |
sessions($owner)->revokeAllExcept($keepFamilyId, $reason) | int | Keeps one session by family id (default LogoutAll); null or an unrecognisable id revokes everything. |
sessions($owner)->revokeOthers($currentAccessReference, $reason) | int | Keeps the session holding that access reference (default LogoutAll); null revokes everything. |
sessions($owner)->revokeAll($reason) | int | Revokes every session (default LogoutAll). |
session($row)->enrich($device, $location) | void | Writes host-supplied device and geo data onto one row (the model or its key). |
session($row)->revoke($reason) | bool | Revokes one row you hold (default Manual). |
sessions($owner) is owner-scoped — another owner’s family, including one of a same-id owner of another type, is unknown to it. session() accepts the RefreshToken model, an int or a string key; an unknown key throws SessionNotFoundException. The verbs on the HasRefreshTokens trait delegate to the same manager — see Sessions.
Show your open-source love
This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.
More ways to support, including cryptoBy donating, you agree to our donation terms.
Want this built into your product?
We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.