DEV Community

I.G
I.G

Posted on • Updated on

How can a client receive the cookie from a server-side?

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)
Enter fullscreen mode Exit fullscreen mode

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"
  )
Enter fullscreen mode Exit fullscreen mode
  • 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 to example.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+}


Enter fullscreen mode Exit fullscreen mode
  • 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)