You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel Passport部署Heroku时加密密钥存储方案咨询

解决Heroku部署Laravel Passport时密钥丢失的问题

我之前也踩过一模一样的坑!Heroku的临时文件系统每次部署都会重置,导致Passport默认存在storage目录里的密钥被清空,令牌失效不说,每次还要手动重置,简直头疼。你的思路方向完全正确——把密钥存到环境变量里,但实现上可以用更简洁可靠的方式,不用重写整个ServiceProvider,我亲测有效的方案如下:

步骤1:生成本地Passport密钥(如果还没生成)

首先在本地项目里生成标准的Passport密钥:

php artisan passport:keys

执行完后,storage目录下会生成oauth-private.key和oauth-public.key两个文件。

步骤2:将密钥存入Heroku环境变量

因为环境变量里不能直接存换行符,我们可以用两种方式处理:

方式A:Base64编码(更稳妥)

把密钥内容转成Base64编码,这样不会有换行符的问题:

# 编码私钥,复制输出的字符串
base64 -w0 storage/oauth-private.key

# 编码公钥,复制输出的字符串
base64 -w0 storage/oauth-public.key

然后把编码后的字符串设置到Heroku环境变量:

heroku config:set PASSPORT_PRIVATE_KEY="这里粘贴编码后的私钥内容"
heroku config:set PASSPORT_PUBLIC_KEY="这里粘贴编码后的公钥内容"

方式B:转义换行符

直接打开密钥文件,把所有换行符替换成\n,然后把整个内容粘贴到环境变量里,比如:

heroku config:set PASSPORT_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEAz...\n-----END RSA PRIVATE KEY-----"
heroku config:set PASSPORT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz...\n-----END PUBLIC KEY-----"

步骤3:配置Laravel从环境变量加载密钥

不需要重写整个PassportServiceProvider,只要在app/Providers/AppServiceProvider.php的boot方法里添加以下代码即可:

如果用Base64编码方式:

use Laravel\Passport\Passport;

public function boot()
{
    if ($this->app->environment('production')) {
        // 解码Base64密钥并加载
        $privateKey = base64_decode(env('PASSPORT_PRIVATE_KEY'));
        $publicKey = base64_decode(env('PASSPORT_PUBLIC_KEY'));

        Passport::privateKey($privateKey);
        Passport::publicKey($publicKey);
    }
}

如果用转义换行符方式:

use Laravel\Passport\Passport;

public function boot()
{
    if ($this->app->environment('production')) {
        // 替换转义的换行符为真实换行
        $privateKey = str_replace('\n', "\n", env('PASSPORT_PRIVATE_KEY'));
        $publicKey = str_replace('\n', "\n", env('PASSPORT_PUBLIC_KEY'));

        Passport::privateKey($privateKey);
        Passport::publicKey($publicKey);
    }
}

步骤4:禁用Passport自动发现并手动注册Provider

在composer.json的extra部分添加dont-discover配置,防止Laravel自动加载默认的PassportServiceProvider:

"extra": {
    "laravel": {
        "dont-discover": [
            "laravel/passport"
        ]
    }
}

然后在config/app.php的providers数组里手动注册官方的PassportServiceProvider:

Laravel\Passport\PassportServiceProvider::class,

为什么你的原方案可能有问题?

重写整个PassportServiceProvider很容易遗漏框架内置的逻辑(比如刷新令牌管理、客户端认证规则等),而用Passport官方提供的privateKey()和publicKey()静态方法,会自动集成所有必要的配置,稳定性更高。

另外,用这个方案后,你再也不需要处理storage目录的权限问题,也不需要每次部署重新生成密钥——所有令牌都会一直有效,完全不受Heroku slug重建的影响。

内容的提问来源于stack exchange,提问作者louisfischer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:01:42