Before working with drf, i knew that, we need to add csrf token to submit the form data.
But in django-rest-framework POST method working without csrf token.
Is it safe?
createGroup=()=>{
let store = JSON.parse(localStorage.getItem('login'))
var url = 'http://127.0.0.1:8000/myapi/creategroup/'
fetch(url,{
method:'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Token '+store.token,
},
body:JSON.stringify({
'name':this.state.groupName,
})
})
.then((response)=>{
response.json()
document.getElementById('i').value=''
this.setState({groupName:''})
})
}
Related
Below are the two files LoginScreen.JS which has a submit handler that submits the input. Here we import the axios instance from login.JS. I have also attached the same working example from PostMan.
login.js
const baseURL='http://127.0.0.1:8000/';
const axiosInstance = axios.create({
baseURL: baseURL,
timeout: 5000,
headers: {
'Content-Type': 'application/json',
accept: 'application/json'
},
});
export default axiosInstance
LoginScreen.js
const submitHandler = (e) => {
e.preventDefault()
axiosInstance
.post(`auth/token/`,{
username: email,
password: password,
grant_type: 'password',
client_id: 'Vqvt1yp2HahF8KgwOS3BrWaCUX8ViDGCrn3VfJkz',
client_secret: 'Vqvt1yp2HahF8KgwOS3BrWaCUX8ViDGCrn3VfJkz'
})
.then((res) => {
localStorage.setItem('access_token', res.data.access);
localStorage.setItem('refresh_token', res.data.refresh);
});
};
views.py
class DeviceView(viewsets.ModelViewSet):
serializer_class = DevicesSerializer
queryset = Devices.objects.all()
permission_classes = [permissions.IsAuthenticated]
Axios Request
axios.delete(`api/devices/${data.id}/`, {}, {
headers: {'X-CSRFToken': csrftoken }
})
.then((response) => {
console.log(response);
}).catch((error) => {
console.log(error);
});
When I carry out this request on my front-end, I get a response of :"DELETE http://localhost:3000/api/devices/4/ 403 (Forbidden)". Where 4 is the ID belonging to the record I would like to delete.
I am currently using Session Authentication in Django and I have passed in my CSRF Token value into the header of my request.
When I use other methods like PUT and POST on forms, they work fine. But, not DELETE
What am I doing wrong to receive this error?
Turns out I just needed to remove the empty body in the Axios request.
axios.delete(`api/devices/${data.id}/`, {
headers: {'X-CSRFToken': csrftoken }
})
.then((response) => {
console.log(response);
}).catch((error) => {
console.log(error);
});
I have my backend in Django and front in Vue.
A user performes login in Vue and via a POST request the creds are sent to a Django JWT login endpoint. This endpoint returns a token which is set in localStorage.
Then I want to check in Vue that the user is logged in. For that another endpoint in Django exists. However, it always returns "AnonymUser". I cannot get how to set this check.
Django:
My settings.py
JWT_AUTH = {
'JWT_ALLOW_REFRESH': True,
'JWT_EXPIRATION_DELTA': datetime.timedelta(hours=1),
'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7),
}
My urls.py
path('check-auth', views.check_if_logged_in, name="check-auth"), # check auth
path('auth/obtain_token', obtain_jwt_token), # obtain token
path('auth/refresh_token', refresh_jwt_token),
My views.py
# Login Check
#csrf_exempt
def check_if_logged_in(request):
authentication_class = (JSONWebTokenAuthentication,)
permission_classes = (IsAuthenticated,)
print(request.user) # returns AnonymUser
check = None
if request.user.is_authenticated:
check = True
else:
check = False
print(check) # returns False
return HttpResponse(f"<html><body>{check}</body></html>")
Vue
obtainToken function
obtainToken(){
var that = this;
fetch(this.endpoints.obtainJWT, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
username: that.django.username,
password: that.django.password
})
}).then(response => response.json()
).then(function(response) {
console.log('auth', response); # get token
that.updateToken(response.token); # update localStorage
that.checkAuthData(); #check auth
});
},
checkAuth function
checkAuthData: function() {
var that = this;
fetch('http://localhost:8000/check-auth', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
token: this.jwt # send token
})
}).then(response => response.json()
).then(function(response) {
console.log('check', response);
});
},
You should include token not in the body, but in the header instead:
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + this.jwt
},
Also, please make sure that in your Django settings in REST_FRAMEWORK DEFAULT_AUTHENTICATION_CLASSES contains JWT authentication:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
...
'rest_framework_simplejwt.authentication.JWTAuthentication',
]
}
I'm having an issue trying to send data with fetch to DJANGO.
I want to send some data to django through fetch but when I debug I receive nothing in the post value, do you know what could be happening?
This is my fetch call:
const defaults = {
'method': 'POST',
'credentials': 'include',
'headers': new Headers({
'X-CSRFToken': csrf_token,
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest'
}),
data:{'name':'A name'},
dataType:'json'
}
const response = await fetch (url, defaults)
When I debug I get an empty querydict in the request.POST
What am I doing wrong?
I am working on password reset and I have used django rest-auth, I have successfully got the token and uid from email link by hitting rest-auth/password/reset/,
but for to confirm I want the token and uid in react form so I can change it how can I get the uid and token which the rest auth return in email link in react js form
axios.post('http://127.0.0.1:8000/rest-auth/password/reset/',payload)
.then(res=>{
console.log(res)
})
.catch(err=>{
console.log(err)
})
its working perfect and it returns me:
http://127.0.0.1:8000/rest-auth/password/reset/confirm/MQ/594-5faaa46be4277e6a1879/
how can I get the uid and token from url in react form?
You should configure your react router to get the params from url.
e.preventDefault();
fetch("http://127.0.0.1:8000/rest-auth/password/reset/confirm/", {
method: 'POST',
headers: {
'Content-Type': 'application/json'
}, body: JSON.stringify({
"new_password1": this.state.new_password1,
"new_password2": this.state.new_password2,
"uid": this.props.match.params.uid,
"token": this.props.match.params.token,
})
})
// .then(response => response.json())
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error)
})