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

在Lambda上用Bref运行Laravel时的AWS Token配置错误问题

在AWS Lambda上使用Bref运行Laravel应用时的AWS凭证配置错误解决

问题描述

我在AWS Lambda上通过Bref运行Laravel应用,serverless.yml配置如下:

service: lambdajob

provider:
  name: aws
  region: us-east-2
  environment:
    APP_ENV: ${sls:stage}
    QUEUE_CONNECTION: sqs
    SQS_QUEUE: lambda-jobs-${sls:stage}
    SQS_PREFIX: https://sqs.us-east-2.amazonaws.com/xxxxxxxxxxx
    CACHE_DRIVER: dynamodb
    DYNAMODB_CACHE_TABLE: testtools-staging-cache
    LOG_CHANNEL: stderr
    TELESCOPE_ENABLED: false
    DB_HOST: ${ssm:/${sls:stage}/DB_HOST}
    DB_DATABASE: ${ssm:/${sls:stage}/DB_DATABASE}
    DB_PASSWORD: ${ssm:/${sls:stage}/DB_PASSWORD}
    DB_USERNAME: ${ssm:/${sls:stage}/DB_USERNAME}
    AWS_BUCKET: staging
  iam:
    role: arn:aws:iam::xxxxxxxx:role/lambda-role

package:
  exclude:
    - .env
    - node_modules/**
    - public/storage
    - resources/js/**
    - rr
    - docker/**
    - storage/logs/**
    - storage/app/**
    - storage/framework/**
    - tests/**

functions:
  worker:
    handler: Bref\\LaravelBridge\\Queue\\QueueHandler
    timeout: 900
    runtime: php-81
    events:
      - sqs:
          arn:
            Fn::GetAtt: [ YourQueueName, Arn ]
          batchSize: 1

plugins:
  - ./vendor/bref/bref
  - serverless-lift

resources:
  Resources:
    YourQueueName:
      Type: AWS::SQS::Queue
      Properties:
        QueueName: lambda-jobs-${sls:stage}
        VisibilityTimeout: 900
        RedrivePolicy:
          maxReceiveCount: 3
          deadLetterTargetArn:
            Fn::GetAtt: [ YourQueueFailedName, Arn ]
    YourQueueFailedName:
      Type: AWS::SQS::Queue
      Properties:
        QueueName: lambda-jobs-failed-${sls:stage}
        MessageRetentionPeriod: 1209600

配置可正常触发Lambda执行任务,但出现以下错误:

Invalid configuration value provided for "token". Expected Aws\Token\TokenInterface|Aws\CacheInterface|array|bool|callable, but got string

我尝试在BrefServiceProvider的fixAwsCredentialsConfig方法中将token转换为Aws\\Token\\Token对象:

private function fixAwsCredentialsConfig(): void
{
    $accessKeyId = $_SERVER['AWS_ACCESS_KEY_ID'] ?? null;
    $sessionToken = $_SERVER['AWS_SESSION_TOKEN'] ?? null;
    $sessionToken = new AwsToken($sessionToken); // 手动添加的代码
     //....
}

但又出现新错误:

taging.ERROR: Object of class Aws\Token\Token could not be converted to string {"exception":"[object] (Error(code: 0): Object of class Aws\\Token\\Token could not be converted to string at /var/task/vendor/aws/aws-sdk-php/src/Signature/SignatureV4.php:328)

尝试创建带__toString方法的自定义Token类后,又遇到GuzzleHttp不接受Token对象的错误。

使用的包版本:

  • laravel: 8.83.27
  • bref/bref: 2.3.2
  • bref/laravel-bridge: 2.4.0
  • aws/aws-sdk-php: 3.317.1

解决方案

1. 恢复BrefServiceProvider的原始代码

不要手动修改fixAwsCredentialsConfig方法,Bref的Laravel桥接已经内置了Lambda环境下的AWS凭证处理逻辑,原始代码会正确将环境变量中的字符串类型token注入到Laravel配置中,同时AWS SDK会自动完成字符串到TokenInterface的转换。

原始方法代码:

private function fixAwsCredentialsConfig(): void
{
    $accessKeyId = $_SERVER['AWS_ACCESS_KEY_ID'] ?? null;
    $sessionToken = $_SERVER['AWS_SESSION_TOKEN'] ?? null;

    if ($accessKeyId === null) {
        return;
    }

    $config = config('services.aws', []);
    $config['key'] = $accessKeyId;
    $config['secret'] = $_SERVER['AWS_SECRET_ACCESS_KEY'] ?? null;
    if ($sessionToken !== null) {
        $config['token'] = $sessionToken;
    }
    $config['region'] = $_SERVER['AWS_REGION'] ?? $config['region'] ?? null;

    config(['services.aws' => $config]);
}

2. 检查Laravel的AWS服务配置

确保config/services.php中的AWS配置未对token做额外处理,保持默认的环境变量引用即可:

return [
    // 其他服务配置...
    'aws' => [
        'key' => env('AWS_ACCESS_KEY_ID'),
        'secret' => env('AWS_SECRET_ACCESS_KEY'),
        'token' => env('AWS_SESSION_TOKEN'),
        'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
        'version' => 'latest',
    ],
    // 其他服务配置...
];

3. 确保Lambda IAM角色权限正确

验证Lambda使用的IAM角色(arn:aws:iam::xxxxxxxx:role/lambda-role)具备以下权限:

  • SQS队列的读写权限
  • DynamoDB缓存表的读写权限
  • RDS数据库的访问权限(如果使用RDS)
  • 其他应用依赖的AWS资源权限

4. 清除Laravel配置缓存

Lambda部署时,确保清除配置缓存,避免旧缓存导致的配置冲突。可以在部署流程中添加php artisan config:clear命令,或者在serverless.yml中配置部署钩子:

functions:
  worker:
    # 现有配置...
    hooks:
      post-package:
        - php artisan config:clear

5. 验证版本兼容性

当前使用的包版本组合是兼容的,如果问题仍存在,可以尝试更新Bref及Laravel桥接到最新稳定版,同时确保aws/aws-sdk-php版本与Bref的要求匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 03:28:13