Passage is a Laravel package by Morcen Chavez that lets your app sit between a client and an external API, forwarding requests and responses while keeping full control over authentication, headers, and payload transformation — all through familiar Laravel routing and middleware.
The typical use case is when you need to call a third-party API from your frontend but don't want to expose API keys, need to normalize payloads, or want to enforce validation and auth logic in one place. Instead of building a custom proxy from scratch, Passage gives you a structured way to do it with minimal boilerplate.
Defining Routes
Routes are registered using the
Passage
facade, right alongside your regular routes. The
{path?}
wildcard captures any sub-path and forwards it upstream:
使用
Morcen\Passage\Facades\Passage
;Passage
::
得到
(
'github/{path?}'
,
GithubPassageController
::班级
(英文):Passage
::
邮政
(
'stripe/{path?}'
,
StripePassageController
::班级
(英文):Passage
::
任何
(
'payments/{path?}'
,
PaymentsPassageController
::班级
(英文):
These support the standard HTTP methods —
get
,
post
,
put
,
patch
,
delete
, 和
any
。
Creating a Handler
Each route points to a handler class that controls how requests are forwarded and responses are returned. Generate one with:
php
工匠
passage:controller
GithubPassageController
Handlers extend
PassageHandler
and can implement three methods:
getOptions()— sets the upstream base URI and Guzzle options (timeouts, headers, etc.)getRequest()— transforms or injects credentials into the outgoing requestgetResponse()— transforms the upstream response before it reaches the client
A minimal handler might look like this:
班级
GithubPassageController
延伸
PassageHandler{
民众
功能
获取选项
()
:
大批{
返回
[
基地
=>
'https://api.github.com/'
,];}
民众
功能
getRequest
(
要求
$请求)
:
要求{
返回
$this
->
withBearerToken
(请求,
配置
(
'services.github.token'
));}}
Note the trailing slash on
base_uri
— it's required for path forwarding to work correctly.
Built-in Authentication Helpers
Passage ships with three authentication traits you can use inside
getRequest()
:
- Bearer token
—
$this->withBearerToken($request, $token) - API密钥
(as a header or query param) —
$this->withApiKey($request, $key)或者$this->withApiKeyQuery($request, $key, 'api_key') - HMAC signing
—
$this->withHmacSignature($request, $secret)
You can also scaffold a handler with auth pre-wired:
php
工匠
passage:controller
StripePassageController
--with-auth=apikeyphp
工匠
passage:controller
PaymentsPassageController
--with-auth=hmac
安全
Passage automatically strips sensitive client headers — cookies, authorization, proxy-authorization — before forwarding requests upstream. If you need to selectively pass certain headers through (like forwarding the client's
Authorization
header), have your handler implement the
AcceptsClientHeaders
interface and define the
allowedClientHeaders()
method to return an allowlist:
班级
GithubPassageController
延伸
PassageHandler
实现
AcceptsClientHeaders{
民众
功能
allowedClientHeaders
()
:
大批{
返回
[
'authorization'
];}}
You can also restrict which hosts can be proxied by setting
PASSAGE_ENFORCE_ALLOWED_HOSTS=true
in your environment.
Inbound Validation and Resilience
Handlers can validate incoming requests before they ever reach the upstream service by implementing
ValidatesInboundRequest
. Define Laravel validation rules in a
rules()
method, and any failures return a 422 — no upstream call is made.
使用
Morcen\Passage\Contracts\ValidatesInboundRequest
;班级
StripePassageController
延伸
PassageHandler
实现
ValidatesInboundRequest{
民众
功能
获取选项
()
:
大批{
返回
[
基地
=>
'https://api.stripe.com/'
];}
民众
功能
规则
()
:
大批{
返回
[
'数量'
=>
[
'必需的'
,
‘整数’
,
'最小值:1'
],
'货币'
=>
[
'必需的'
,
'细绳'
,
'size:3'
],];}}
For resilience,
withRetry()
adds automatic retry with exponential backoff:
班级
PaymentsPassageController
延伸
PassageHandler{
民众
功能
获取选项
()
:
大批{
返回
数组合并
([
基地
=>
'https://payments.example.com/'
],
$this
->
withRetry
(
3
,
200
),
// 3 retries, 200ms initial delay(英文):}}
Passage also supports response caching for
GET
/
HEAD
routes and streaming responses for large payloads.
Useful Artisan Commands
php artisan passage:list— lists all registered proxy routesphp artisan passage:health— checks connectivity to upstream services
You can also disable all proxying without touching your routes by setting
PASSAGE_ENABLED=false
在你的
.env
。
Passage is a clean solution for scenarios where you need a lightweight API proxy inside an existing Laravel app without reaching for a full enterprise gateway. Learn more and explore the source code on GitHub 。





