---
title: "Refresh Tokens for Laravel — docs | Roundly"
description: "Developer docs for Refresh Tokens for Laravel: hashed rotating refresh tokens, reuse detection, device sessions, polymorphic owners, events and pruning."
url: https://roundly-consulting.com/open-source/docs/refresh-tokens-for-laravel
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

Open source

# Refresh Tokens for Laravel

Install

`composer require roundly-consulting/refresh-tokens-for-laravel`

Requires: PHP ^8.4 · Laravel ^12.0|^13.0

[GitHub](https://github.com/roundly-consulting/refresh-tokens-for-laravel) [Packagist](https://packagist.org/packages/roundly-consulting/refresh-tokens-for-laravel) [Donate (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Patreon](https://www.patreon.com/cw/roundly)

## Overview

Opaque, rotating refresh tokens and device sessions for Laravel. Tokens are stored only as SHA-256 digests, rotated by a single-query compare-and-swap so exactly one concurrent refresh wins, and replaying a spent token revokes its whole family automatically. Any Authenticatable model — users, API clients, admins — holds sessions in one polymorphic table, with a stable session id, device data and one-call “log out everywhere”. MIT-licensed, with zero third-party runtime dependencies — just Laravel plus Roundly’s own crypto, enums and toolkit packages.

### What you get

#### Hashed at rest

Only a SHA-256 digest is stored under a unique index; the plaintext is returned once. Optional HMAC pepper on top.

#### Atomic rotation

A single-query compare-and-swap: of N concurrent refreshes exactly one wins — no transaction, no row lock.

#### Reuse detection

Replaying a rotated token revokes the whole family, denies its access tokens and fires an alert event. Always on.

#### Device sessions

A stable session id per login, device and geo data, and one-call revoke of one, all others or every session.

#### Polymorphic owners

Users, API clients, admins — any Authenticatable model shares one table, with guard-scoped redemption.

#### Sliding + absolute lifetimes

A sliding TTL per rotation plus a hard absolute cap per session, both overridable per login.

#### Facade, DI or actions

One RefreshTokens facade over an injectable manager and single-purpose actions, plus a recording fake that still runs every call.

### Documentation

#### [Installation](https://roundly-consulting.com/open-source/docs/refresh-tokens-for-laravel/installation.md)

Install via Composer, publish and run the migration, and add the HasRefreshTokens trait to every owner model.

#### [Configuration](https://roundly-consulting.com/open-source/docs/refresh-tokens-for-laravel/configuration.md)

Every config key, default and env variable — table, key type, lifetimes, token length, hashing, rotation grace and pruning.

#### [Owners & key types](https://roundly-consulting.com/open-source/docs/refresh-tokens-for-laravel/owners.md)

Polymorphic owners: users, API clients and admins share one table, isolated by morph class and key, on bigint, UUID or ULID keys.

#### [The RefreshTokens facade](https://roundly-consulting.com/open-source/docs/refresh-tokens-for-laravel/facade.md)

The whole RefreshTokens facade at a glance — issue, redeem, rotate, revoke and prune, plus the sessions() and session() handles.

#### [DI and actions](https://roundly-consulting.com/open-source/docs/refresh-tokens-for-laravel/without-facade.md)

Inject RefreshTokensManager instead of calling the facade, or run the action behind any method — the same code either way.

#### [Issuing tokens](https://roundly-consulting.com/open-source/docs/refresh-tokens-for-laravel/issuing-tokens.md)

Issue a refresh token linked to your access token via IssueContext or the fluent builder; the plaintext is returned exactly once.

#### [Redeeming & rotating](https://roundly-consulting.com/open-source/docs/refresh-tokens-for-laravel/rotation.md)

Atomically redeem a token with anti-double-spend, rotate it in one call, scope redemption to one owner type, and handle failures.

#### [Reuse detection](https://roundly-consulting.com/open-source/docs/refresh-tokens-for-laravel/reuse-detection.md)

Replaying a rotated token revokes the whole family, denies its access tokens and fires RefreshTokenReuseDetected — always on.

#### [Revocation & logout](https://roundly-consulting.com/open-source/docs/refresh-tokens-for-laravel/revocation.md)

Log out one token or every session, record why with RevocationReason, and revoke everything on a password change.

#### [Sessions](https://roundly-consulting.com/open-source/docs/refresh-tokens-for-laravel/sessions.md)

List, find and revoke device sessions by their stable family id — the machinery behind a “your devices” screen.

#### [Device & location enrichment](https://roundly-consulting.com/open-source/docs/refresh-tokens-for-laravel/device-enrichment.md)

Attach host-parsed browser, OS, device type and geolocation to a session with enrich() — typically from an async job.

#### [Access-token revocation](https://roundly-consulting.com/open-source/docs/refresh-tokens-for-laravel/access-token-revoker.md)

Bind an AccessTokenRevoker so every revoked session or family also kills its paired access token, e.g. via a JWT jti denylist.

#### [Events](https://roundly-consulting.com/open-source/docs/refresh-tokens-for-laravel/events.md)

Four typed events — issued, redeemed, revoked and reuse-detected — carrying ids and scalars only, never the model or plaintext.

#### [Security & hashing](https://roundly-consulting.com/open-source/docs/refresh-tokens-for-laravel/security.md)

SHA-256 digests at rest, an optional HMAC pepper, validated config, serialization safety and the host-owned boundary.

#### [The token model](https://roundly-consulting.com/open-source/docs/refresh-tokens-for-laravel/token-model.md)

Scopes, helpers, casts and hidden attributes on the RefreshToken model, and how to swap in your own subclass.

#### [Database schema](https://roundly-consulting.com/open-source/docs/refresh-tokens-for-laravel/database-schema.md)

The refresh\_tokens columns, plus RefreshTokenBlueprint for reproducing or adopting the schema in your own migration.

#### [Artisan commands](https://roundly-consulting.com/open-source/docs/refresh-tokens-for-laravel/commands.md)

Prune dead tokens on your own schedule with refresh-tokens:prune or a named model:prune, and inspect config with about.

#### [Exceptions](https://roundly-consulting.com/open-source/docs/refresh-tokens-for-laravel/exceptions.md)

Every typed exception the package throws, when it throws, and the base class to catch them all.

#### [Testing](https://roundly-consulting.com/open-source/docs/refresh-tokens-for-laravel/testing.md)

RefreshTokens::fake() records every issue, redeem, rotate, revoke, enrich and prune; FakeAccessTokenRevoker and the factory cover the rest.

#### [Requirements](https://roundly-consulting.com/open-source/docs/refresh-tokens-for-laravel/requirements.md)

PHP 8.4+ and Laravel 12 or 13, with zero third-party runtime dependencies. Companion Roundly packages install automatically.

## 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 crypto](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## 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.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source.md)
