Populate a cookie with a Django csrf token - django

i need to understand something.
I've a rest server on server A (django-rest-framework). An app on server B (angularjs) requests the rest server.
I want to add authentication. each time i request http://serverA/api-auth/login/, it returns 403 because i don't pass the csrf token.
So, in my app.js, i've added :
.run(function($http, $cookies) {
$http.defaults.headers.post['X-CSRFToken'] = $cookies.csrftoken;
});
now, fine, i can send the csrf token.
My question is, how can i populate the cookie ? Do i have to do a get() to obtain the token before posting ? Because currently my cookie is empty :(
Thank you

You cannot use SessionAuthentication method if you don't share the same domain. In your case the OAuth2Authentication is the way to go.

Assuming your angularjs code using jquery ajax to post, you can put the csrf token into the meta tag
<!--<meta name="csrf-token" content="{{csrf_token}}">-->
Then setup your jquery ajax method to include the csrf token.
jQuery(document).ajaxSend(function(event, xhr, settings) {
if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
//var token = $('meta[name="csrf-token"]').attr('content');
var csrftoken = $.cookie('csrftoken');
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}..............
});

Related

How can I fix "CSRF token missing" error?

I'm building a web application with Django as my backend framework and DjangoRestFramework as webAPI, React Native as the frontend, and apisauce as an HTTP client. When I try to make a POST request from the frontend to the backend, I get this error :
CSRF Failed: CSRF token missing
I don't get the error when I use postman.
Is it good if I comment this out django.middleware.csrf.CsrfViewMiddleware ?
CSRF tokens are used to prevent cross-site request forgery attacks. This error implies that you are not providing CSRF in your POST request. I was wondering about your reason to use apisauce instead of axios, since axios automatic inclusion of the CSRF token.
Meaning you would not need to comment "django.middleware.csrf.CsrfViewMiddleware"
and ensure that your app is CSRF attack free.
EDIT:
Ok, if you must use apisauce, you can manual set the csrf token using following code:
import apisauce from 'apisauce';
const api = apisauce.create({
baseURL: 'https://yourbackend.com/api',
});
const csrftoken = getCookie('csrftoken');
api.setHeader('X-CSRFToken', csrftoken);
api.post('/endpoint', {
data: 'yourdata',
})
.then((response) => {
console.log(response);
})
.catch((error) => {
console.log(error);
});
function getCookie(name) {
// you may have to change this function a bit
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop().split(';').shift();
}

Why csrf token must be put in body for POST requests and not in headers in Django Rest Framework?

I would like to know the reason why we must put the csrf token in the body for POST requests (key csrfmiddlewaretoken) and in the headers for the others (key X-CSRFToken)?
You can use the header in case of a POST request as well. Indeed, this is often done for POST requests with AJAX (and other requests with side-effects). This is demonstrated in the Setting the token on the AJAX request section of the documentation [Django-doc]:
Finally, you’ll need to set the header on your AJAX request. Using the
fetch() API:
const request = new Request(
/* URL */,
{
method: 'POST',
headers: {'X-CSRFToken': csrftoken},
mode: 'same-origin' // Do not send CSRF token to another domain.
}
);
fetch(request).then(function(response) {
// ...
});

Send X-CSRF Token to a Django server using XHTTP Request or jQuery Ajax

I've been trying to make a POST to my Django application via XHTTP Request and jQuery with no correct result at all.
The fact is that the Django app is on one of my subdomains, and the web app is in another, not being part of the Django app, just only a separated app.
I've been reading the docs, but none of this works.
All of my subdomains are in the ALLOWED HOSTS list and in the CORS ORIGIN WHITELIST, and the petition works correctly with GET, but POST returns me a Forbidden 403 error telling CSRF Cookie not found.
This is the code of my petition.
var petition = new XMLHttpRequest();
petition.open('POST','http://localhost:8000/login/',true);
petition.setRequestHeader("X-CSRFToken",sessionStorage["csrf_token"]);
petition.send()
I already have stored the CSRF cookie in the session storage with this function.
function storeCSRFToken(){
var token;
$.ajax({
url : 'http://localhost:8000/token',
type: "GET",
dataType : "json",
success: function( data ){
token = data.csrf_token;
sessionStorage['csrf_token'] = token;
}
});
}
Any clue of what is going wrong?

Send a post request from an expressjs endpoint to django

I am trying to implement the following workflow.
Populate an html form
Submit it
The endpoint that is receiving the request(expressjs) does some processing and sends a request with the req.body to another backend(django)
Django returns a response to expressjs
The problem is that I am being stuck at the csrf level and more specifically getting this error:
invalid csrf token
403
ForbiddenError: invalid csrf token
Here is the code that I am using for the request:
router.post('/registration', function (req, res, next) {
axios.post('http://localhost:8000/register_extended/', JSON.stringify(req.body), {
'Content-Type': 'application/json'
}).then(() => {
console.log('success')
}).catch(() => {
console.log('failure')
})
res.send('respond with a resource');
});
});
and here are my middlewares
app.use(bodyParser.urlencoded({ extended: true }));
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(csrfMiddleware);
How can I provide a valid csrf token for my needs? Axios is supposed to the handling itself, thats why I chose it.
Django uses CSRF tokens to prevent CSRF attacks from untrusted domains. You can whitelist your site or IP where express is running to make post requests without a CSRF token. Add this to your Django 'settings.py':
CSRF_TRUSTED_ORIGINS = [
"yoursite.runningexpress.here.com"
]

VueJS Authentication with Django REST Key

I can retrieve a key after logging in through my Django REST API, but then I am wondering how I should store that key. I'm not really using Django, but I imagine I have to store the cookie myself then or something. I'm using Axios for VueJS to interact with the API. I am using django rest auth to get the token.
Keep it easy to Local Storage or SessionStorage after get token from Backend-Response and then pass it in every Request in Axios Header-config.
DRF auth Token get it from header with this format:
Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b
Add this section code to your Axios configs to get token from LocalStorage.
Axios.interceptors.request.use(
(config) => {
let token = window.localStorage.getItem("token");
if (token) {
config.headers["Authorization"] = `Token ${token}`;
}
return config;
},
(error) => {
return Promise.reject(error);
}
);