django sessionid, csrrftoken and vue axios - django

I have a question about using vue axios frontend and Django backend in cors-domain environment.
My cookie can use set-Cookie sessionid and csrftoken but frontend can't get these parameters to save to my document.
If I use my chrome explorer, the application cookie is empty but I can find the cookie in response cookie header.
But I won't use this csrftoken to backend verify in other POST AJAX, how can I resolve it to verify?
I try a lot of settings, but not work in using #csrf_protect function, though just remove it and use #csrf_exempt can work.
How can I keep csrftoken work in this situation?
Thanks.
The followings are what I use settings.
axios settings
axios.defaults.headers.get['Accept'] = 'application/json'
axios.defaults.headers.post['Content-Type'] = 'application/json'
axios.defaults.withCredentials = true
axios.defaults.xsrfCookieName = 'csrftoken'
axios.defaults.xsrfHeaderName = 'X-CSRFToken'
Django settings
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.middleware.gzip.GZipMiddleware',
)
CORS_ALLOW_HEADERS = (
'accept',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-CSRFToken',
'X-CSRFToken',
'csrftoken',
'x-requested-with',
)
CORS_ALLOW_METHODS = (
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
)
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True

Related

Windows authentication with Django and Angular?

I am trying to implement the single sign-on using Angular, Django, IIS server.
In IIS windows authentication is enabled.
Angular intercepter code :
intercept(req: HttpRequest<any>, next: HttpHandler):Observable<HttpEvent<any>> {
console.log("in intercept")
req = req.clone({
withCredentials: true });
return next.handle(req); }
Django settings.py:
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.RemoteUserMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',]
AUTHENTICATION_BACKENDS = ( 'django.contrib.auth.backends.RemoteUserBackend',)
CORS_ORIGIN_ALLOW_ALL = True
ALLOWED_HOSTS = ["*"]
Getting error:
(IP-address) 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.
Try this configuration in settings.py
CORS_ORIGIN_ALLOW_ALL = True CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_CREDENTIALS = True # This one is required when you are using withCredentials: true
The problem will lie in the Django setup, please have a look at this link: https://stackoverflow.com/a/38162454/4587598
If at first try won't work, strip all settings.py and setup from scratch, firstly checking if CORS issue does not occur and afterwards add authentication complexity.
try django-cors-headers
pip install django-cors-headers
And set it up
In your settings.py
INSTALLED_APPS = (
...
'corsheaders',
...
)
You will also need to add a middleware class to listen in on responses:
MIDDLEWARE = [ # Or MIDDLEWARE_CLASSES on Django < 1.10
...
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
...
]
CorsMiddleware should be placed as high as possible, especially before any middleware that can generate responses such as Django's CommonMiddleware
CORS_ORIGIN_ALLOW_ALL = True

No 'Access-Control-Allow-Origin' header is present on the requested resource Django and ReactJS

Currently I have Django 1.98 as Backend and React as Front End.
I'm getting this error:
Access to XMLHttpRequest at
'https://mywebsite:8000/uploads/vtt/' from origin
'http://localhost:3000' has been blocked by CORS policy: No
'Access-Control-Allow-Origin' header is present on the requested
resource.
I installed django-cors-headers==2.4.0 on my virtualenviroment
This is my settings.py file:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'uploads.core',
'corsheaders',
]
MIDDLEWARE_CLASSES = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
CORS_ORIGIN_ALLOW_ALL = True
CSRF_TRUSTED_ORIGINS = ['http://127.0.0.1:3000','http://localhost:3000','http://localhost:8000','https://mywebsite:8000','https://myapp.firebaseapp.com','https://mywebsite:8088']
CSRF_COOKIE_NAME = "csrftoken"
CSRF_HEADER_NAME = [
'HTTP_X_CSRFTOKEN'
]
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
CORS_ORIGIN_WHITELIST = ['http://localhost:3000','https://mywebsite:8088']
CORS_ALLOW_METHODS = (
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
)
CORS_ALLOW_HEADERS = (
'accept',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
)
Any idea how to solve it?
Thanks.
django-cors-headers is reasonably fool-proof and your configuration seems correct to me.
There is however a gotcha I've had issues with too:
Your uploads directory is likely not served through Django, but by the server directly as a static file (best practice and nearly default behaviour in Django). Even the built-in development server will serve static files without invoking your Django app.
Since your app is not invoked, django-cors-headers cannot apply a CORS header to those responses.
Make sure https://mywebsite:8000/uploads/vtt/ is the correct URL.
In my case, I used the wrong port because my API used a different port.
I replaced 8000 with 52130.
Try adding:
CORS_ORIGIN_WHITELIST = (
'example.com',
'localhost:3000',
'127.0.0.1:3000',
'more.domain.or.subdomains'
)
Don't forget add the middleware too
MIDDLEWARE = [ # Or MIDDLEWARE_CLASSES on Django < 1.10
...
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
...
]
I had the same issue, and I think is a problem with:
SECURE_SSL_REDIRECT = True
I don't know the impacts over disabling it, but setting it to:
SECURE_SSL_REDIRECT = False
This make the cors problem gone.

JWT Token Authentication with Django Rest Framework

I am having some issues with token authentication on my Django-Rest application with a react native frontend. I have always used Session Authentication, and this is my first time setting up a project with these requirements.
I pip installed -
djangorestframework_simplejwt
I know the tokens are being generated when I hit the endpoint api/token
I am able to retrieve them on the front end. My problem occurs when I try to hit a list route in the backend and the error I get back is as follows.
{
"detail": "Authentication credentials were not provided."
}
I thought this could be a cors issue, or an issue with my axios request, but I am fairly certain they are setup correctly. The other issue is the authentication and permissions classes in my viewset which is where my intuition is telling me this problem is coming from.
Relevant settings.py info --
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'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',
'social_django.middleware.SocialAuthExceptionMiddleware',
]
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_METHODS = (
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
)
CORS_ALLOW_HEADERS = (
'accept',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
)
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
'rest_framework.authentication.SessionAuthentication',
)
}
Viewset/Serializer/Url
class WorkoutViewSet(ModelViewSet):
model = apps.get_model('backend', 'Workout')
queryset = model.objects.all()
serializer_class = serializers.WorkoutSerializer
authentication_classes = (authentication.TokenAuthentication,)
permission_classes = (permissions.IsAuthenticated,)
class WorkoutSerializer(serializers.ModelSerializer):
class Meta:
model = apps.get_model('backend', 'Workout')
fields = ('name', 'is_complete', 'allow_copy', 'workout_goal', 'user')
router.register(r'workouts', views.WorkoutViewSet, base_name='workouts')
Axios Request
export const workouts = (token) => {
return axios({
method: 'get',
url: 'http://localhost:8000/workouts',
headers: { 'authorization': `Bearer ${token}`}
})
}
Thanks for any help/direction.
in your viewset, you have specified authentication_classes where you set TokenAuthentication.
That means, for your WorkoutViewSet you specified to use only TokenAuthentication - which uses Token prefix in the header, hence you get 'Credentials not provided'
If you want to use the JWT token authentication - you should either set it explicitly here or remove it and let the default chosen classes handle the authentication

angular2/Django rest application browser asks for login after application login

I am building an app with angular2 on frontend and Django rest on backend. Even after I login to my application, browser asks for login once again like following:
This happens each day, but not on consecutive logins in the same day. Why does this happen?
My Django rest configuration code:
MIDDLEWARE_CLASSES = [
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
]
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
}
and angular2 service:
login(username: string, password: string) {
let body = JSON.stringify({
'username' : username,
'password': password
});
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.post(this._authenticationUrl + 'login/', body, options)
.map(this.extractData)
.catch(this.handleError)
}
Why does this happen?
I had following in my code which was causing problem:
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
You should remove
'rest_framework.authentication.BasicAuthentication',
from DEFAULT_AUTHENTICATION_CLASSES, and keep
'rest_framework.permissions.IsAuthenticated',
in DEFAULT_PERMISSION_CLASSES.

Disable All Authentication Django

I have an API written in Django, with authentication with cookie and sessionid.
Now I want to add a end-point public, with any kind of authentication, but I can't access the end-point.
What I've done:
URL:
url(r'^api/public_end_point/?$', csrf_exempt(views.publicEndPoint.as_view()), name='public_end_point')
Views:
class publicEndPoint(APIView):
#api_view(['POST'])
#permission_classes([permissions.AllowAny,])
def post(self, request, *args, **kwargs):
return Response({"success": True, "content": "Hello World!"})
Some Ideas about what am I missing here ?
Thanks
EDIT
Settings:
MIDDLEWARE_CLASSES = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
# MY MIDDLEWARE #
'config.middleware.EnforceLoginMiddleware',
'config.middleware.AuditMiddleware',
'config.middleware.ExceptionMiddleware',
]
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_FILTER_BACKENDS': ('rest_framework.filters.DjangoFilterBackend',),
'PAGE_SIZE': 20
}
[15/Feb/2017 15:57:16] "POST /api/public_end_point HTTP/1.1" 302 0
[15/Feb/2017 15:57:16] "GET /sign/base.html?nu=/api/public_end_point HTTP/1.1" 200 2906
Just add PERMISSION_CLASSES = (,) to your view as class variable, you don't need to use a decorator.
Just for informational purposes - Django Rest Framework by default uses BasicAuthentication and SessionAuthentication such that you either need to be logged in or provide Basic authentication credentials to access the api.
If you need your own custom token authentication, you need to override AUTHENTICATION_CLASSES in your drf settings.
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
# add your own authentication class
)
}