React and Django CORS header ‘Access-Control-Allow-Origin’ missing - reactjs

I have a React frontend app that needs to send a request to my Backend written in Django
My frontend and backend are now on the same domain but different subdomains.
But I'm getting some CORS problems, more specificly, CORS header ‘Access-Control-Allow-Origin is missing.
I found a lot of questions on stackoverflow on how you need to install django-cors-headers but it simply doesn't work for me.
my current backend configuration:
settings.py
INSTALLED_APPS = [
...,
"corsheaders",
...,
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'debug_toolbar.middleware.DebugToolbarMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.locale.LocaleMiddleware',
'simple_history.middleware.HistoryRequestMiddleware',
]
ALLOWED_HOSTS = ["*"]
CORS_ALLOW_ALL_ORIGINS = True
views.py (where I create the api)
#csrf_exempt
#api_view(["GET"])
#permission_classes([AllowAny])
#xframe_options_exempt
def create_user_and_ci(request):
try:
# code to execute
return Response({"status": "Succes"}, status.HTTP_200_OK)
except:
return Response({"status": "Error"}, status.HTTP_500_INTERNAL_SERVER_ERROR)
And then on my frontend I execute this:
fetch("https://subdomain.mydomain/get/id", {
method: 'GET',
headers: {
'Authorization': `Token mytoken`,
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
// Other possible headers
}
}).then((res) => console.log(res));
UPDATE
When I make the call without giving the headers, it works, problem is I need to send my token to my backend for validation

Foremost, this CORS error is due to the fact that your frontend is not on the same domain as your Django API/Backend, so all the Django responses need to contain the CORS related headers here.
I found this post about adding a custom HTTP header with a middleware in Django, this might help you here.

Install this package:
pip install django-cors-headers
INSTALLED_APPS = [
...,
"corsheaders",
...,
]
CORS_ALLOWED_ORIGINS = [
http://127.0.0.1:3000, #For React Project
http://127.0.0.1:8000 #For Django Project
]
In MiddleWare add this in the list
MIDDLEWARE = [
"corsheaders.middleware.CorsMiddleware",]

Related

ReactJS with graphql CORS Issue with django backend

I have running django backend on http://127.0.0.1:8000 and I want to request it with reactjs frontend.
As you can see below, I can see the successful response in the Insomnia app.
But, When I want a request with reactjs frontend, I get a CORS ERROR.
I check the request in the inspect networks and I saw a similar request payload with insomnia.
install django-cors-headers:
pip install django-cors-headers
Add corsheaders to INSTALLED_APPS in settings.py:
INSTALLED_APPS = [
...,
"corsheaders",
...,
]
Add CorsMiddleware to your middlewares in settings.py:
MIDDLEWARE = [
...,
"corsheaders.middleware.CorsMiddleware",
"django.middleware.common.CommonMiddleware",
...,
]
Now you can set your allowed origins in settings.py like this:
CORS_ALLOWED_ORIGINS = [
"https://example.com",
"https://sub.example.com",
"http://localhost:8080",
"http://127.0.0.1:9000",
]
More info in this link.

What is the correct syntax for adding the xframe header module to cra rewired?

I'm trying to return the X-Frame-Options in my create react app (rewired) but I'm not sure of the correct syntax to use to add the function to my existing override. How do I do this properly?
module.exports = override(
fixBabelImports("react-bulma-components", {
libraryName: "react-bulma-components",
libraryDirectory: "lib/components"
}),
{devServer: function(configFunction) {
return function(proxy, allowedHost) {
const config = configFunction(proxy, allowedHost)
config.headers = {
'X-Frame-Options': 'Deny'
}
return config
}
}},
...addCompressions()
);
The front end is a CRA (rewired) non-static webapp
The backend is a node app hosted seperately
I've also tried changing the buildpack to this buildback in order to add the configuration in a static.json file, but that breaks a lot of different things, uses a different server etc.
The proper way of doing this, is by not doing it... is useless, dont waste your time. Let's remember that yow CRA Page will executed on the browser and it won't send you headers/data or anything, instead it will be send as well by Nginx/Apache/NodeJs something else.
Firefox even says the same: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
Note: Setting X-Frame-Options inside the element is useless! For instance, has no effect. Do not use it! X-Frame-Options works only by setting through the HTTP header, as in the examples below.
Heroku
You can configure different options for your static application by writing a static.json in the root folder of your application.
Custom Headers
Using the headers key, you can set custom response headers. It uses the same operators for pathing as Custom Routes.
{
"headers": {
"/": {
"Cache-Control": "no-store, no-cache"
},
"/assets/**": {
"Cache-Control": "public, max-age=512000"
},
"/assets/webfonts/*": {
"Access-Control-Allow-Origin": "*"
}
}
}
https://blog.heroku.com/using-http-headers-to-secure-your-site

Missing Patch method with corsheaders only on chrome

I have a Django app that's using corsheaders package and its in settings.py like this:
INSTALLED_APPS = [ ..., corsheaders, ...]
...
MIDDLEWARE = [
    # on top
    "corsheaders.middleware.CorsMiddleware",
    "django.middleware.common.CommonMiddleware",
    ...
]
...
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True
When I'm trying to do a PATCH request on Google Chrome after the OPTIONS method I get this:
The Access-Control-Allow-Methods is missing PATCHand the next request fails with CORS methods error.
But I tried the same method on Firefox and its working as intended.
Seems like you need to set allowed origins explicitly, not by using the wildcard i.e. *:
CORS_ALLOWED_ORIGINS = [
"https://example.com",
"https://sub.example.com",
"http://localhost:8080",
"http://127.0.0.1:9000"
]
Also, set all HTTP verbs:
CORS_ALLOW_METHODS = [
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
]
Read more:
https://pypi.org/project/django-cors-headers/
Chrome Cross-Domain PATCH request not working
CORS_ALLOW_ALL_ORIGINS = True or CORS_ORIGIN_ALLOW_ALL = True (OLD name) is equal to using wildcard * : L131 django-cors-headers middleware.py file

Cloud Run service gives 404 error when trying to access from hosted site

I have set up a site using firebase hosting where I would like to send requests to an API to send emails. Locally, this works perfectly. However, after pushing the API using Google Cloud run, I had run into errors when trying to access the API online using the hosted site. I had used the following firebase tutorial to try and set this up.
https://firebase.google.com/docs/hosting/cloud-run#node.js_1
I was able to deploy it with no issues, however, when I try to access the API through POST requests, it returns a 404 error. The site itself was developed with React.JS and the backend API was developed using Golang.
firebase.json:
{
"hosting": {
"public": "build",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"run": {
"serviceId": "api",
"region": "europe-west1"
}
}
]
}
}
JavaScript where the call to the API is being made:
const response = await fetch(this.state.endpoint+"/sendEmail", {
method: "POST",
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json'
},
});
Golang router where the routing is being handled:
router := mux.NewRouter().StrictSlash(true)
router.HandleFunc("/sendEmail", SendEmail)
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil))
Again, running this locally has no issues but running it on the cloud returns a 404 error.
Update
I have now fixed the issue that was pointed out by #guillaumeblaquiere, that was the issue to do with the code itself. I did not call the router and so the routing was not taking place. Below is the fixed version
log.Print("api: starting server")
router := mux.NewRouter().StrictSlash(true)
router.HandleFunc("/sendEmail", SendEmail)
port := os.Getenv("PORT")
fmt.Println(port)
if port == "" {
port = "8080"
}
log.Printf("api: listening on port %s", port)
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), router))
The only issue left is that I have to call the API using the URL directly, not using rewrites.

403 Forbidden when trying to access API via DRF

I am trying to access a django server using django-rest-framework from angular using the following service:
myapp.factory("GetData", ["$resource",function($resource) {
return $resource(
"http://local/path/**/users/:username/",
{},
{
"query": {
method: "GET",
isArray: true,
headers:{
"Content-Type":"application/json"
}
}
},
{
stripTrailingSlashes:false
}
);
}]);
When I put the URL in the browser, I get the desired output, but the problem is that when I try to access via Angular, in my console I am getting a 403 forbidden error. Can anyone explain to me whats causing this. and how I can possibly fix this issue.
My url.py looks as follows:
from rest_framework.routers import DefaultRouter
from .views import UserViewSet
router = DefaultRouter()
router.register(prefix='users', viewset=UserViewSet)
urlpatterns = router.urls
My views.py file is as follows:
from django.shortcuts import render
from django.http import HttpResponse
from rest_framework import viewsets
from .models import users
from .serializers import UserSerializer
class UserViewSet(viewsets.ModelViewSet):
queryset = users.objects.all()
serializer_class = UserSerializer
I think the 403 forbidden is coming to browser block cross origin requests.
You need to enable allow CORS at your API server by setting appropriate headers.
You can lookup https://github.com/ottoyiu/django-cors-headers
For this you need to add in your installed apps.
'corsheaders'
And just set to test it out. Check for fine tuned settings in the docs.
CORS_ORIGIN_ALLOW_ALL = True
Edit
Also you need to add this in your middlewares.
'corsheaders.middleware.CorsMiddleware',
I managed to fix the problem by combining what #Bipul Jain suggested https://stackoverflow.com/a/42044910/7210105 (above) and also altering this link in my $resource
"http://local/path/**/users/:username/"
I removed http://local/path from the link and the 403 forbidden error went away.

Resources