Conclusion
A client-side can receive the cookie from a server-side configuring "SameSite=none" when performing set-cookie.
But you need to configure Secure attribute as well, otherwise the current modern browsers don't store the cookie for security.
Environment
- Frontend: React
- Serverside: API Gateway + Lambda + FastAPI(Python)
Server-side
# functions/hub.py
from fastapi import FastAPI
from mangum import Mangum
from .routers import authentication_router
app = FastAPI()
app.include_router(authentication_router, tags=["authentication"])
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Mangum converts a request and response of FastAPI into event and context of AWS Lambda.
lambda_handler = Mangum(app)
FastAPI restricts OPTIONS requests (preflight requests) by default, so even if you allow them on the API Gateway side, if you do not allow them on the FastAPI side, a 405 error will be returned.
So, you need to explicitly include CORS headers in the response in FastAPI middleware so that the browser can make preflight requests.
# functions/routers/authentication.py
from fastapi import APIRouter, Request, Response
authentication_router = APIRouter()
class RequestBody(BaseModel):
email: str
password: str
@authentication_router.post("/signin")
def sign_in(requset_body: RequestBody, request: Request, respose: Response):
# Get tokens from Cognito
tokens = signin(requset_body.email, requset_body.password)
response.set_cookie(
key="access_token",
value=tokens.access_token,
httponly=True,
secure=True,
samesite="none"
)
Enabling HttpOnly, prevent the cookie from being accessed by JavaScript like
document.cookie
.Enabling Secure, the cookie is send only via HTTPS. HTTP is prohibited to send it.
"Samesite=none" is to allow the cookie to be sent over a cross-site request. (e.g. from
example.apigateway.com
toexample.vercel.app
as below)
API Gateway | Vercel |
---|---|
example.apigateway.com | example.vercel.app |
Remarks
If configuring "SameSite=Lax" or "SameSite=Strict", client-side can't receive the cookie from the server-side.
※Exclaimation mark is displayed at the header of set-cookie in the Network tab of the dev tool of your browser with the mesasge (e.g. "This attempt to set a cookie via a Set-Cookie header was blocked because it had the "SameSite=Lax" attribute but came from a cross-site response which was not the response to a top-level navigation.")
Configuration for Serverless Framework
# serverless.yml
provider:
httpApi:
cors:
allowedOrigins:
- https://example.vercel.app
- http://localhost:3000
allowedHeaders:
- Content-Type
- Set-Cookie
allowedMethods:
- OPTIONS
- GET
- POST
- PUT
- DELETE
allowCredentials: true
functions:
hub:
name: hub
handler: hub.lambda_handler
events:
- httpApi:
# ANY method is used to catch all HTTP methods
method: any
# /{proxy+} route works as a catch-all route
path: /{proxy+}
Only the origins in allowedOrigins can access API Gateway.
Setting allowCredentials to true, enables cookies to be sent across domains.
/{proxy+} catches all requests that don't match other routes already configured in API Gateway.
Top comments (0)