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);
}
);
Related
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();
}
I just can't wrap my head around how the authentication is done if I use Firebase auth and I wish to connect it to my django rest backend.
I use the getIdTokenResult provided by firebase as such:
async login() {
this.error = null;
try {
const response = await firebase.auth().signInWithEmailAndPassword(this.email, this.password);
const token = await response.user.getIdTokenResult();
/*
No idea if this part below is correct
Should I create a custom django view for this part?
*/
fetch("/account/firebase/", {
method: "POST",
headers: {
"Content-Type": "application/json",
"HTTP_AUTHORIZATION": token.token,
},
body: JSON.stringify({ username: this.email, password: this.password }),
}).then((response) => response.json().then((data) => console.log(data)));
} catch (error) {
this.error = error;
}
},
The only thing I find in the firebase docs is this lackluster two line snippet: https://firebase.google.com/docs/auth/admin/verify-id-tokens#web
where they write
decoded_token = auth.verify_id_token(id_token)
uid = decoded_token['uid']
# wtf, where does this go?
# what do I do with this? Do I put it in a django View?
I found a guide here that connects django rest to firebase: https://www.oscaralsing.com/firebase-authentication-in-django/
But I still don't understand how its all tied together. When am I supposed to call this FirebaseAuthentication. Whenever I try to call the login function I just get a 403 CSRF verification failed. Request aborted.
This whole FirebaseAuthentication class provided by the guide I linked to above - should I add that as a path on the backend?
path("firebase/", FirebaseAuthentication, name="api-firebase"),
Which is the api endpoint my frontend calls?
This may be a stupid question. So, I am using Django for my backend and React for my frontend. The goal is to only show the objects that belong to the user that is making the request. Since Django takes care of authentication, do I need to use Redux, or any other framework for that matter, for authentication?
Couldn't I just do something like: request.user.something.objects.all() on my backend when I receive the Axios request from my frontend? Do Axios request even provide the user?
Yes you can store data in rudex thats why logically you can also use rudex store as authentication . but if you change route or refresh page this data will be destroy . Axios in general send Brear?Basic authentication . For that you need to also configure your back-end api like that .You can also make authentication buy using browser session storage or localstorage . For that you have to pass authentication code from you header request Like as .
fetch(URL+'/api/user/profile', {
method: 'GET',
headers: {
'Authorization': 'Bearer ' + sessionStorage.getItem('token')
}
}).then(response => {
return response.json();
})
.then(profile => {
// console.log(profile);
this.setState({
profile : profile[0]
});
});
No. Redux is optional. Store your token in local storage you can use mobx, redux and the context api for your user authentication
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"
]
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);
}..............
});