2

I am making a login in next js and I make a request to an api that is made in fastapi to return me a cookie the error occurs when I do the fetch in the front-end exactly when I put credentials: 'include' I have done the process only with html and javascript and I save the cookie but when I do it in next.js I get the error

Access to fetch at 'http://127.0.0.1:8000/' from origin 'http://localhost:3000' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.

FastAPI

from fastapi import APIRouter, Response, status
from config.db import conn
from models.user import users
from schemas.user import User
from cryptography.fernet import Fernet
import datetime
from starlette.status import HTTP_204_NO_CONTENT
from funcions.funcions_jwt import validate_jwt, write_jwt
from fastapi.responses import JSONResponse
import http.cookies as Cookie

key = Fernet.generate_key()
f = Fernet(key)

user = APIRouter()

@user.post("/login", tags=["users"], status_code=200)
async def login(response: Response, user: User):
    print(user)
    response.set_cookie(key="my_cookie", value=write_jwt(dict(user)), httponly=True)
    return {"message": "Ok"} 
from fastapi import FastAPI, Request
from routes.user import user
from dotenv import load_dotenv
from fastapi.middleware.cors import CORSMiddleware
import http.cookies as Cookie
from fastapi.responses import JSONResponse

app = FastAPI(
        title="Campesinos API",
        description="API with FastAPI",
        version="0.0.1",
        openapi_tags=[{
            "name": "users",
            "description": "Operations with users"
        }]
)

origins = [
    "*",
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["Content-Type"],
)


load_dotenv()

app.include_router(user)

Next JS

import { LoginModel } from "../models";

export const login = (credencials: LoginModel) => {
    console.log('credencials', credencials);
    const url = 'http://127.0.0.1:8000/login';
    fetch(url, {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
        },
        body: JSON.stringify(credencials),
    }).then((res) => {
        console.log('res');
        return res.json()
    });
};

1 Answers1

0

We cannot allow credentials when allow_origins = ['*'] as per the FastAPI documentation. So, the working code snippet for adding CORS middleware would be as follows:

origins = [
    "*",
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_methods=["*"],
    allow_headers=["Content-Type"],
)

I have removed allow_credentials=True here. You can also modify it to allow credentials by specifying the allowed origins like:

origins = [
    "http://localhost:5000/",
    # allowed origins
]

Some additional suggestions:

  1. Specifying to allow Content Type header is not needed.
  2. I would suggest you to load origins from environment variables.
Aadarsha
  • 176
  • 1
  • 13