Download the PHP package labrodev/laravel-dpop without Composer
On this page you can find all versions of the php package labrodev/laravel-dpop. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download labrodev/laravel-dpop
More information about labrodev/laravel-dpop
Files in labrodev/laravel-dpop
Package laravel-dpop
Short Description RFC 9449 DPoP for Laravel — issues EC P-256-bound JWTs and verifies DPoP proofs on protected routes.
License MIT
Homepage https://github.com/labrodev/laravel-dpop
Informations about the package laravel-dpop
Laravel DPoP
RFC 9449 Demonstration of Proof-of-Possession (DPoP) for Laravel. Issues EC P-256-bound JWTs via a built-in token endpoint and verifies DPoP proofs on protected routes via middleware.
What is DPoP?
DPoP (RFC 9449) is an application-level mechanism for binding access tokens to a client's public key. Each request carries a short-lived, single-use proof-of-possession JWT signed with the client's private key. Even if a bearer token is stolen, it cannot be used without the corresponding private key.
Requirements
| Dependency | Version |
|---|---|
| PHP | ^8.4 |
| Laravel | ^12.0 |
firebase/php-jwt |
^6.0 |
web-token/jwt-library |
^3.4 |
spatie/laravel-data |
^4.0 |
Installation
Run the interactive installer:
This writes all DPOP_* environment variables to .env and publishes the config file.
Manual installation
Publish the config:
Add the required environment variables to your .env:
Configuration
After publishing, edit config/dpop.php:
Token Endpoint
A POST endpoint is registered automatically at the URI defined in dpop.token_route (default: POST /api/dpop/token).
Request
The jwk must be an EC P-256 public key. Including the private key component d will return a 422.
Response
The response always includes Cache-Control: no-store.
Issued JWT claims
| Claim | Value |
|---|---|
iss |
config('app.url') |
sub |
JWK thumbprint (RFC 7638) |
jkt |
JWK thumbprint (RFC 7638) |
scp |
Array of requested scopes |
iat |
Issued-at timestamp |
exp |
iat + dpop.jwt.lifetime |
Protecting Routes
Apply the dpop middleware to any route or route group:
Accessing the verified token
After the middleware passes, the decoded JWT payload is available from the request:
Idempotency Middleware
The package ships an optional dpop.idempotency middleware for unsafe HTTP methods (POST, PUT, PATCH, DELETE).
Clients must send an Idempotency-Key header (UUID format):
| Scenario | Response |
|---|---|
| First request | Normal response |
| Replay with same body | Cached response + Idempotency-Replayed: true header |
| Replay with different body | 409 Conflict + {"error": "E.I.2"} |
| Missing / invalid key | 422 Unprocessable + {"error": "E.I.1"} |
Error Codes
All errors return JSON {"error": "<code>"} with the appropriate HTTP status.
| Code | Step | HTTP | Description |
|---|---|---|---|
D.E.1 |
1 | 401 | Missing or non-Bearer Authorization header |
D.E.2 |
2 | 401 | Invalid JWT signature |
D.E.3 |
3 | 401 | JWT expired or missing exp claim |
D.E.4 |
4 | 401 | Missing jkt claim in JWT |
D.E.5 |
5 | 401 | Missing DPoP proof header |
D.E.6 |
6 | 401 | DPoP proof typ is not dpop+jwt |
D.E.7 |
7 | 401 | DPoP proof alg is not ES256 or key is not EC P-256 |
D.E.8 |
8 | 401 | DPoP proof JWS cryptographic signature invalid |
D.E.9 |
9 | 401 | htm does not match request method |
D.E.10 |
10 | 401 | htu does not match request URL |
D.E.11 |
11 | 401 | iat outside acceptable clock skew |
D.E.12 |
12 | 401 | jti replayed (anti-replay) |
D.E.13 |
13 | 401 | JWK thumbprint does not match jkt claim |
D.E.14 |
— | 422 | JWK contains private key d |
C.O.1 |
— | 401 | Origin not in allowed origins list |
S.1 |
— | 401 | Required scope not present in token |
E.I.1 |
— | 422 | Missing or invalid Idempotency-Key |
E.I.2 |
— | 409 | Idempotency key reused with different request body |
Client Example
A minimal JavaScript client using the Web Crypto API:
Development
License
MIT — see LICENSE.
All versions of laravel-dpop with dependencies
firebase/php-jwt Version ^7.0
illuminate/cache Version ^12.0 || ^13.0.0
illuminate/http Version ^12.0 || ^13.0
illuminate/pipeline Version ^12.0 || ^13.0
illuminate/routing Version ^12.0 || ^13.0
illuminate/support Version ^12.0 || ^13.0
spatie/laravel-data Version ^4.0
spatie/laravel-package-tools Version ^1.92
web-token/jwt-library Version ^4.1