I'm trying to implement session based authentication the first time using React and Django Rest Framework, but there's some weird thing I don't understand.
I have a pretty standard Login view, so I send POST request from React with username and password, I got response with status 200 and I can see cookies in the response with Chrome developer tools.
But these cookies aren't being saved.If I do the same POST request with Rest plugin for Chrome - it saves them.
Am missing something here since it's my first time? Or should I save it manually somehow?
Here's my request with axios. Do I need to add something here?
const sendLogin = () => {
if (login && password) {
axios.post(SERVER_ADDRESS + 'login/', {username: login, password: password})
.then(response => {
if (response.status !== 200) {
handleClick();
}
else {
history.push('/');
}
})
}
}
Related
I'm building a separated VueJS/Django app where Django will communicate with the Vue frontend using JSON. In order to be able to use the standard session authentication and django-allauth i will deploy the two apps on the same server and on the same port.
Here is my problem: after i log in from the Vue app using Axios, i don't receive any response but i notice that a session is created on the db, so i'm assuming that i'm getting logged in. But if i try to reach and endpoint that prints request.user.is_authenticatedi get False, and request.user returns Anonymous, so i'm not logged in anymore. How can i solve this?
Here is my Axios code:
bodyFormData.append('login', 'root');
bodyFormData.append('password', 'test');
axios({
method: "post",
url: "http://127.0.0.1:8000/accounts/login/",
data: bodyFormData,
withCredentials: true,
headers: { "Content-Type": "application/json" },
})
.then(function (response) {
//handle success
console.log(response);
})
.catch(function (response) {
//handle error
console.log(response);
});
I think Django-Allauth supports AJAX authentication on its urls, but i don't understand how to make it return something and how can my Vue app stay authenticated once i submit the Axios form. Any advice is welcome!
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?
I'm trying to send a POST request from a Vue.js template to my API created with Django.
When sending I get a 403 CSRF token missing or incorrect error. Since I separated the front and the back, I don't have a view with {csrf_token} on the Django side.
How do I send my form?
I tried some exemples on the web using cookies but i'm beginners and need more explaination about the POST subject and CSRF
I have a Djano View (and urls associated) juste like this :
def get_csrf_token(request):
token = get_token(request)
return JsonResponse({'token': token})
Whe i'm requesting the url, obtained the JSON with the token.
And on the Front side i'm using this method to get the Token :
getToken: function() {
this.loading = true;
this.$http.get('/qualite/get-token/')
.then((response) => {
this.token =response.data;
this.loading = false;
})
.catch((err) => {
this.loading = false;
console.log(err);
})
},
addNc: function() {
let headers = {
'Content-Type': 'application/json;charset=utf-8'
};
if(this.token !== '') {
headers['HTTP_X-XSRF-TOKEN'] = this.token
}
this.loading = true;
this.$http.post('/qualite/api/nc/',this.newNc, {headers: headers})
.then((response) => {
this.loading = false;
})
.catch((err) => {
this.loading = false;
console.log(err)
})
},
For the CSRF you get by default after user login aside with the session, if you're using SessionAuthentication (It's the default authentication used in DRF).
You have to send it with each request in the header, you can refer the this link to know more about the header sent, as it's name is changed and can be configured.
Note also that in the settings you have to make sure that CSRF_COOKIE_HTTPONLY is set to False (which is the default), to be able to read it from the client side JS.
Another path would be removing CSRF enforcement per requests (But it's highly not recommended for security concerns), you can find more about this in the answer here.
Use a Token-based authentification.
Same issue i was encountered with,
the problem was, i had used Class based view and at the time of registered the url i forget to mention as_view() with class Name.
ex:- class PostData(APIView)
before :- path('post_data', PostData)
after correction:- path('post_data', PostData.as_view())
I'm using ember-simple-auth and I can see that the authentication token is returned and that my custom authenticator is putting it (code-wise) into the session.
I can use wireshark to see that the token comes back but I can't debug into the authenticator code - I can't even use debug statements as the redirect wipes the network session on google chrome.
However, it isn't in the session (google chrome tools) and the session isn't considered authenticated.
Why is the lock code correctly popping up the auth0 dialog but not saving the session? I don't really think it is something with this code but rather a config or initialization setting I'm unaware of.
I expect the session to be saved in the _setupFutureEvents as the first thing it does.
Any ideas what I can try to get it to work?
(/app/authenticators/lock.js) authenticate (options) {
return new Ember.RSVP.Promise((res) => {
this.get('lock').show(options, (err, profile, jwt, accessToken, state, refreshToken) => {
if (err) {
this.onAuthError(err);
} else {
var sessionData = { profile, jwt, accessToken, refreshToken };
// pass the NEW auth0 session data into future events
this.afterAuth(sessionData).then(response => res(this._setupFutureEvents(response)));
}
});
});
},
afterAuth (data) {
return Ember.RSVP.resolve(data);
},
_setupFutureEvents (data) {
// set the session info here
this.get('sessionData').setProperties(data);
this._clearJobs();
this._scheduleExpire();
if (this.get('hasRefreshToken')) {
this._scheduleRefresh();
}
return this.get('sessionData');
},
I am confused. What does "password_grant" type of authenticator expect from server for it to say "successfully" authenticated when it is trying to get its token from remote server?
It seems as long as server return 200 status code, it always authenticated. Am I missing something here?
// app/controllers/login.js
import Ember from 'ember';
export default Ember.Controller.extend({
session: Ember.inject.service('session'),
actions: {
authenticate() {
let { identification, password } = this.getProperties('identification', 'password');
this.get('session').authenticate('authenticator:oauth2', identification, password).catch((reason) => {
this.set('errorMessage', reason.error || reason);
});
}
}
});
If the user password didn't pass authentication on the server side, the server should return 401 status code?
More:
Based on this, server should response with 400.
So, based on what I have researched, once server return 200 code and some JSON data, even any empty JSON data, ember-simple-auth will take it as authenticated. Returning 400 will fall into the catch clause.
Maybe someone can just comfirm with me on this? I guess oauth2.0 is supposed to be implemented on the server side. Ember-simple-auth simply just comply to the standard and assume that "200 status code" means authenticated and token should be inside the json payload returned.