Ok so some background first. I am working on an app and wanted to try out bref; I knew that it had a Laravel integration layer so I figured this should be relatively painless.
I installed the packages that their docs recommend, I installed the serverless binary, etc., everything good so far.
I am able to deploy the site AWS without issue. When I browse to the CloudFront distribution, everything shows up correctly. I can run migrations, again without issue.
My problem is when I go to actually register an account, for example. As soon as I submit the form, I get the 419 Page Expired error. Now I know on most normal Laravel apps, that usually means the CSRF token isn't being sent, but I can see in the developer tools that it's part of the POST request, so I don't think that's it. But now I'm stuck as to what else I can look for.
My checklist:
- It can't be anything database connection or permission related, since the migrations run normally
- The site key is set in the
APP_KEY environment variable that's being pulled down from the Parameter Store (I've currently got it set to a datatype of "String", just in case "SecureString" has some extra decryption step necessary to read and use it)
- I've confirmed that it is posting back to the correct CloudFront URL (I have not set up any custom domains yet)
- In the BrefServiceProvider, they automatically set the trustedproxy values to 0.0.0.0/0 and 2000::0/3
- They also check if the session driver is
file, and if so, automatically change the config to use the cookie driver
Any ideas, no matter how wild they might be, are very welcome here.
serverless.yml:
service: my-real-site-name-goes-here
provider:
name: aws
# The AWS region in which to deploy (us-east-1 is the default)
region: us-east-1
# Environment variables
environment:
APP_DEBUG: bref-ssm:/my-real-site-name-goes-here-prod/APP_DEBUG
APP_ENV: production # Or use ${sls:stage} if you want the environment to match the stage
APP_KEY: bref-ssm:/my-real-site-name-goes-here-prod/APP_KEY
APP_NAME: bref-ssm:/my-real-site-name-goes-here-prod/APP_NAME
APP_URL: bref-ssm:/my-real-site-name-goes-here-prod/APP_URL
AWS_BUCKET: bref-ssm:/my-real-site-name-goes-here-prod/AWS_BUCKET
AWS_URL: bref-ssm:/my-real-site-name-goes-here-prod/AWS_URL
AWS_USE_PATH_STYLE_ENDPOINT: bref-ssm:/my-real-site-name-goes-here-prod/AWS_USE_PATH_STYLE_ENDPOINT
BROADCAST_DRIVER: bref-ssm:/my-real-site-name-goes-here-prod/BROADCAST_DRIVER
CACHE_DRIVER: bref-ssm:/my-real-site-name-goes-here-prod/CACHE_DRIVER
CASHIER_CURRENCY: bref-ssm:/my-real-site-name-goes-here-prod/CASHIER_CURRENCY
DB_CONNECTION: bref-ssm:/my-real-site-name-goes-here-prod/DB_CONNECTION
DB_DATABASE: bref-ssm:/my-real-site-name-goes-here-prod/DB_DATABASE
DB_HOST: bref-ssm:/my-real-site-name-goes-here-prod/DB_HOST
DB_PASSWORD: bref-ssm:/my-real-site-name-goes-here-prod/DB_PASSWORD
DB_PORT: bref-ssm:/my-real-site-name-goes-here-prod/DB_PORT
DB_USERNAME: bref-ssm:/my-real-site-name-goes-here-prod/DB_USERNAME
DEMO_MODE_ENABLED: bref-ssm:/my-real-site-name-goes-here-prod/DEMO_MODE_ENABLED
DYNAMODB_CACHE_TABLE: !Ref CacheTable
FILESYSTEM_DISK: bref-ssm:/my-real-site-name-goes-here-prod/FILESYSTEM_DISK
LOG_CHANNEL: bref-ssm:/my-real-site-name-goes-here-prod/LOG_CHANNEL
LOG_DEPRECATIONS_CHANNEL: bref-ssm:/my-real-site-name-goes-here-prod/LOG_DEPRECATIONS_CHANNEL
LOG_LEVEL: bref-ssm:/my-real-site-name-goes-here-prod/LOG_LEVEL
MAIL_FROM_ADDRESS: bref-ssm:/my-real-site-name-goes-here-prod/MAIL_FROM_ADDRESS
MAIL_FROM_NAME: bref-ssm:/my-real-site-name-goes-here-prod/MAIL_FROM_NAME
MAIL_MAILER: bref-ssm:/my-real-site-name-goes-here-prod/MAIL_MAILER
MYSQL_ATTR_SSL_CA: bref-ssm:/my-real-site-name-goes-here-prod/MYSQL_ATTR_SSL_CA
QUEUE_CONNECTION: sqs
RAPIDAPI_FOOTBALL_HOST: bref-ssm:/my-real-site-name-goes-here-prod/RAPIDAPI_FOOTBALL_HOST
RAPIDAPI_NHL_MLB_HOST: bref-ssm:/my-real-site-name-goes-here-prod/RAPIDAPI_NHL_MLB_HOST
SQS_QUEUE: ${construct:jobs.queueUrl}
iam:
role:
statements:
- Effect: Allow
Resource: !GetAtt CacheTable.Arn
Action:
- dynamodb:DescribeTable
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
- Effect: Allow
Action: ssm:GetParameters
Resource: "arn:aws:ssm:${aws:region}:${aws:accountId}:parameter/*"
- Effect: Allow
Action: s3:*
Resource:
- !Sub "${Storage.Arn}" # the storage bucket
- !Sub "${Storage.Arn}/*" # and everything inside
package:
# Files and directories to exclude from deployment
patterns:
- "!node_modules/**"
- "!public/storage"
- "!resources/assets/**"
- "!storage/**"
- "!tests/**"
functions:
# This function runs the Laravel website/API
web:
handler: public/index.php
runtime: php-81-fpm
timeout: 28 # in seconds (API Gateway has a timeout of 29 seconds)
events:
- httpApi: "*"
# This function lets us run artisan commands in Lambda
artisan:
handler: artisan
runtime: php-81-console
timeout: 720 # in seconds
events:
- schedule:
rate: rate(1 minute)
input: '"schedule:run"'
plugins:
# We need to include the Bref plugin
- ./vendor/bref/bref
- serverless-lift
constructs:
website:
type: server-side-website
assets:
"/build/*": public/build
"/fonts/*": public/fonts
"/images/*": public/images
"/vendor/*": public/vendor
"/favicon.ico": public/favicon.ico
"/robots.txt": public/robots.txt
"/android-chrome-192x192.png": public/android-chrome-192x192.png
"/android-chrome-512x512.png": public/android-chrome-512x512.png
"/apple-touch-icon.png": public/apple-touch-icon.png
"/browserconfig.xml": public/browserconfig.xml
"/favicon-16x16.png": public/favicon-16x16.png
"/favicon-32x32.png": public/favicon-32x32.png
"/mstile-150x150.png": public/mstile-150x150.png
"/safari-pinned-tab.svg": public/safari-pinned-tab.svg
"/site.webmanifest": public/site.webmanifest
jobs:
type: queue
worker:
handler: Bref\LaravelBridge\Queue\QueueHandler
runtime: php-81
timeout: 60 # seconds
resources:
Resources:
Storage:
Type: AWS::S3::Bucket
CacheTable:
Type: AWS::DynamoDB::Table
Properties:
AttributeDefinitions: # only keys are defined here, other attributes are dynamic
- AttributeName: id # adds a mandatory id field
AttributeType: S # the type of id is a string
BillingMode: PAY_PER_REQUEST # billed for each request instead of paying for a constant capacity
TimeToLiveSpecification: # deletes cache keys automatically based on a ttl field which contains a timestamp
AttributeName: ttl
Enabled: true
KeySchema:
- AttributeName: id
KeyType: HASH # the type of key, HASH means partition key (similar to primary keys in SQL)