Home > Software engineering >  Python - Flask Error : Origin has been blocked by CORS policy
Python - Flask Error : Origin has been blocked by CORS policy

Time:07-12

I have a problem with my api python using flask. When I try to access api from view, the browser says "Access to fetch at 'http://127.0.0.1:8859/api/calculadora' from origin 'http://127.0.0.1:5500' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled."

My api uses blueprints for endpoints. I have tried to solve the problem using flask-cors but it has not worked for me. (With Postman work correctly)

Project's structure: Project's structure

My code is the following:
main.py:

from flask import Flask , jsonify , request
from flask_cors import CORS, cross_origin
from dotenv import load_dotenv

from app.routes.auth import routesAuth
from app.routes.calculadora import calculadora_blueprint

app = Flask(__name__)
CORS(app, support_credentials=True)

app.register_blueprint(routesAuth, url_prefix="/api")
app.register_blueprint(calculadora_blueprint, url_prefix="/api")

if __name__ == "__main__":
    load_dotenv()
    app.run(None , 8859 , True)

calculadora.py:

from flask import Blueprint , request , Flask
from flask_cors import cross_origin , CORS

from app.function_jwt import validarToken

from app.models.Hipoteca import Hipoteca
from app.models.HipotecaDTO import HipotecaDTO
from app.models.Simulacion import Simulacion
from app.services.impl.HipotecaFijaServicio import HipotecaFijaServicio
from app.services.impl.HipotecaVariableServicio import HipotecaVariableServicio
from app.services.impl.SimulacionServicio import SimulacionServicio

calculadora_blueprint = Blueprint("calculadora_blueprint", __name__)

hipotecaFijaServicio = HipotecaFijaServicio()
hipotecaVariableServicio = HipotecaVariableServicio()
simulacionServicio = SimulacionServicio()

@calculadora_blueprint.before_request
def validar_token_middleware():
    print(request.headers['Authorization'].split(" ")[1])
    token = request.headers['Authorization'].split(" ")[1]
    return validarToken(token,False)

@calculadora_blueprint.route("/calculadora", methods=["POST"])
@cross_origin(supports_credentials=True)
def calculadora():

    print(request.headers['Authorization'].split(" ")[1])
    # Almacenar el JSON recibido en un objeto Hipoteca
    print(type(request.json['capitalInmueble']))
    hipoteca = Hipoteca(request.json['totalIntereses'], request.json['capitalInmueble'],
                        request.json["capitalAportado"] , request.json["prestamo"] , request.json["cuota"],
                        request.json["plazo"] , request.json["plazoRestante"] , request.json["tasaInteres"],
                        request.json["tipoInteres"] , request.json["fechaNacimiento"] , request.json["ahorros"],
                        request.json["nomina"],request.json["otrosPrestamos"], request.json["esPrimeraVivienda"] )


    simulacion = Simulacion(None,None,None)
    simulacionServicio.generarHipoteca(hipoteca,simulacion)
    porcentaje = simulacionServicio.calcularProbabilidad(simulacion)

    hipoteca.amortizaciones = list()

    if request.json["tipoInteres"] == "fijo":
        hipotecaFijaServicio.calcularAmortizaciones(hipoteca)
        print("cuota"   str(hipoteca.cuota))
    else:
        hipotecaVariableServicio.calcularAmortizaciones(hipoteca)

    response = HipotecaDTO(hipoteca,porcentaje)

    return response.toJson()

fetch on js:

fetch('http://127.0.0.1:8859/api/calculadora',{
    method: "POST",
    body: JSON.stringify(s),
    headers: {
        "Content-Type": "application/json",
        "Authorization" : "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6Ik1hcmNvcyIsInBhc3N3b3JkIjoxMjMsImV4cCI6MTY1NzcxNTM2Nn0.CyYX0X11ilUD8Rj-JI4Tb6ri1gb6n9HH_hsZKseA5BE"
    }
})

.then(res => res.json())
.then(data => {
    console.log(data.porcentaje)
    imprimirTabla(data.hipoteca.amortizaciones);
    imprimirTarjetas(data)

})
.catch(err => console.log(err))

EDIT 1

I found the error but I can't fix it. If I remove the middleware, it works perfectly.But I need it to validate the JSON web token

calculadora.py:

@calculadora_blueprint.before_request
def validar_token_middleware():
    print(request.headers['Authorization'].split(" ")[1])
    token = request.headers['Authorization'].split(" ")[1]
    return validarToken(token,False)

Output without middleware

CodePudding user response:

I usually use CORS in the following way

from flask_cors import CORS
app = Flask(__name__)
cors = CORS(app, resources={r"/*": {"origins": "*"}})

The asterisk "*" is a wildcard, so using it will allow access to the defined endpoint from any origin. If you want only access to 127.0.0.1:8859 to be allowed, try using the following:

cors = CORS(app, resources={r"/api/calculadora": {"origins": "127.0.0.1:8859"}}) 

The documentation of how to use CORS with Flask can be seen from here

CodePudding user response:

The Flask app you posted runs on port 8859:

if __name__ == "__main__":
    load_dotenv()
    app.run(None , 8859 , True)

Then you get:

"Access to fetch at 'http://127.0.0.1:8859/api/calculadora' from origin 'http://127.0.0.1:5500' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin'

Are you using an other Flask application on port 5500, as reverse proxy? In that case it is the one that needs CORS clearance.

When you reach the webapp on :5500 through the browser and it fetches from :8859, the browser complains that the webapp on :5500 doesn't have CORS clearance. Instead, when you reach :8859 through the Postman server, there is no browser involved and so no CORS complain. More on CORS.

Also, it's not safe to post bearer tokens.

  • Related