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.
Related
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",]
I need help. https://apis.google.com/js/api.js is getting blocked by csp on my production react app. I have added the webpack config as well.
new CspHtmlWebpackPlugin({
// 'base-uri': "'self'",
// 'object-src': "'none'",
'script-src': [
"'unsafe-inline'",
"'unsafe-eval'",
"https://apis.google.com/js/api.js",
"https://www.wiris.net/demo/plugins/app/configurationjs",
"https://as.alipayobjects.com/g/component/fastclick/1.0.6/fastclick.js",
"https://cdn.mathjax.org/mathjax/latest/MathJax.js",
],
'style-src': ["'unsafe-inline'", "'self'", "'unsafe-eval'"]
})
i am using csp-html-webpack-plugin
Suggestions to check:
1. Check if there is a Redirect
If this is getting replicated in your local environment - try to see if there is a redirect (in the chrome network tab).
For privacy reasons, in 301/302 redirects to a separate domain (that is not in the allow-list), the CSP report will contain the ORIGINAL request url, which can be very confusing.
2. Try allowing the full domain
i.e. allow https://apis.google.com instead of https://apis.google.com/js/api.js and see if it persists.
3. Extra tip
There is no need/use for 'unsafe-eval' in style-src. You can remove it.
Looks like you have miconfigured csp-html-webpack-plugin - you have to include both HtmlWebpackPlugin and CspHtmlWebpackPlugin plugins in your webpack config because last one is based on the first one:
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CspHtmlWebpackPlugin = require('csp-html-webpack-plugin');
module.exports = {
// rest of webpack config
plugins: [
new HtmlWebpackPlugin()
new CspHtmlWebpackPlugin({
// CSP config here:
enabled: true,
'script-src': [
"'unsafe-inline'",
"'unsafe-eval'",
"'self'",
"https://apis.google.com/js/api.js",
"https://www.wiris.net/demo/plugins/app/configurationjs",
"https://as.alipayobjects.com/g/component/fastclick/1.0.6/fastclick.js",
"https://cdn.mathjax.org/mathjax/latest/MathJax.js",
],
'style-src': ["'unsafe-inline'", "'self'"],
processFn: defaultProcessFn,
})
]
}
Also do check:
which CSP do you really have got in the <meta equiv="content-security-policy" content="..."> tag.
do you have any Content-Security-Policy HTTP response header in the Dev Tool because some middleware(e g. Helmet) can publish its own default CSP.
And please add to the question a CSP error message from the browser console.
I wanna use react as frontend with django as backend
I tried
urlpatterns = [
path('api/',include('api.urls')),
path('admin/', admin.site.urls),
path('',include('frontend.urls')),
]
frontend is the app contains react
frontend app urls
urlpatterns = [
path('/',index)
]
def index(request):
return render(request,'frontend/index.html')
i wanna use index.html any other route
project/urls.py
urlpatterns = [
path('api/',include('api.urls')),
path('admin/', admin.site.urls),
path('', include('frontend.urls')), # This has to be the last item!
]
frontend/urls.py
#...
from django.urls import re_path
#...
urlpatterns = [
re_path(r".*", index) # RegExpr: any character is correct
]
Django routing and react routing don't have to mix. They are completely separate from each other. You get your API data from the django routes and then create you own routes on the front-end with react-router. Read this for some context: https://www.digitalocean.com/community/tutorials/build-a-to-do-application-using-django-and-react.
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.
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.