Reputation: 149
I have an api built in FastAPI running on localhost:8000
and a NextJS frontend running on localhost:3000
. I'm using HttpOnly
cookie to store the JWT token after user authentication. But for some reason the cookie is not set in chrome and subsequent requests are not authenticated. When I test the mechanism in insomnia it is working, but on the frontend it doesn't. Here is my actual setup.
The login endpoint:
@router.post("/signin", response_model=SigninResponseSchema)
def sign_in(
response: Response,
*,
user_credentials: SigninSchema,
db: Session = Depends(database.get_db),
) -> any:
signin_infos = auth_service.authenticate_user(db, user_credentials=user_credentials)
sign_in_response = SigninResponseSchema(
status="successful",
access_token=signin_infos["access_token"],
user_data=signin_infos["user_data"],
user_roles=signin_infos["user_roles"]
)
token = jsonable_encoder(sign_in_response.access_token)
response.set_cookie(
"Authorization",
value=f"Bearer {token}",
httponly=True,
secure=True,
samesite="none",
max_age=1800,
expires=1800,
)
return sign_in_response
The cors setup:
origins = [
"http://localhost:3000"
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["GET", "POST", "HEAD", "OPTIONS"],
allow_headers=["Access-Control-Allow-Headers", "Content-Type", "Authorization", "Access-Control-Allow-Origin","Set-Cookie"],
)
How do I solve the problem? I've already taken a look to several solutions on the internet but none of them is working. What could be the problem ?
Upvotes: 3
Views: 5072
Reputation: 25
Your setup on the FastAPI side looks good, the issue is likely in your front-end application.
One thing that jumps out is that you're making your requests from http://localhost:3000
which isn't over HTTPS, and you're setting your cookie with secure=True
. Ideally you should be running your front-end app locally over HTTPS and making requests from https://localhost:3000
.
Here's a couple more things to check on the client side:
{withCredentials: true}
credentials: 'include'
withCredentials: true
"Access-Control-Allow-Origin": "http://localhost:3000"
Credit: This answer to a similar question got me unstuck from a similar issue
Upvotes: 2