In Django, if CSRF_COOKIE_HTTPONLY is enabled, javascript isn't allowed to access CSRF cookie, so it means they also can't get CSRF token inside the cookies. Here is how I handled Django authorization inside AngularJS.
Solution
I know developers are busy, so I will put the solution on the top of posts and explain detail after that.
Following Django document, AngularJS or any javascript could get the CSRF token from the DOM instead of cookie if cookie is http only.
Step 1: Put a tag in static html so Django middleware can put token to the HTML DOM.
# Django put CSRF token to DOM
{% csrf_token %}
Step 2: Implement an interceptor to get CSRF token from the DOM
import { Injectable } from '@angular/core';
import { HttpEvent, HttpRequest, HttpHandler, HttpInterceptor } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class DjangoCSRFInterceptor implements HttpInterceptor {
intercept(httpRequest: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const token = (
document.querySelector('[name=csrfmiddlewaretoken]') as HTMLInputElement
).value;
return httpRequest.clone({ headers: httpRequest.headers.set('X-CSRFToken, token) });
}
}
Step 3: Put HttpInterceptor to your Angular module providers
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: DjangoCSRFInterceptor, multi: true }
]
Now your angular code should be able to get CSRF token and put in any request.
Django CSRF_COOKIE_HTTPONLY
CSRF_COOKIE_HTTPONLY is a flag that enables http only for CSRF cookie. Although http only is a best practice for security, Django foundation points that it doesn't offer any practical protection and encourage developer to turn this flag off.
However, there are many reasons that force us to enable http only with CSRF cookie. One of the reasons in my case is my security auditor report that it is a risk and should be fixed.
What is Angular HttpInterceptor
In Angular, interceptor allows us to intercept a http request or response. By intercepting request/response, we can modify its context as we want.
Ideally, we can implement an interceptor to add X-CSRFToken
to headers. And Django will accept this request.
Conclusion
In conclusion, I would like to note that this post just a note of how I handled the angular request when CSRF_COOKIE_HTTPONLY is enable. In most of situation, we should leave this flag as default value (False). But if you have to enable it, hopefully this post can save your time.
Happy sharing, happy Code with Beer🍺🍺🍺!!!
Top comments (0)