django rest + axios put request error 403 - django

I've read the duplicates and nothing seems to be working. I can do the put request directly from the form in the url but I can't seem to get the axios request working.
I tried:
CSRF with Django, React+Redux using Axios
https://gist.github.com/paltman/490049a64fa4115a2cea
my view.py:
class FrequencyList(generics.ListCreateAPIView):
queryset = Frequency.objects.all()
serializer_class = FrequencySerializer
class FrequencyDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Frequency.objects.all()
serializer_class = FrequencySerializer
My axios request:
axios({
method: 'put',
url: '/f/'+id,
data: {
item: item,
},
}).then(function (response) {
this.setState({needReceipt: true});
})
.catch(function (error) {
console.log(error);
});
In my settings.py:
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.AllowAny',
),
}
in my webpack.config.dev.js:
const axios = require('axios');
axios.defaults.xsrfHeaderName = "X-CSRFToken";
axios.defaults.xsrfCookieName = "csrftoken";

try this
axios.put('/f/'+id, { item: item })
.then(function(response){
this.setState({needReceipt: true});
});
Reference

Related

http only cookie authentication and logging out user

I am authenticating user with http only cookies which contains jwt tokens.
Heres all my settigns require to use cookies.
settings.py
CORS_EXPOSE_HEADERS = ["Content-Type", "X-CSRFToken"]
CORS_ALLOW_CREDENTIALS = True
# CORS_ALLOW_HEADERS = ["Set-Cookie",]
SESSION_COOKIE_SAMESITE = "Lax"
SESSION_COOKIE_HTTPONLY = True
CSRF_COOKIE_HTTPONLY = True
CSRF_COOKIE_SAMESITE = "None"
CSRF_COOKIE_SECURE = True
CSRF_TRUSTED_ORIGINS = ["http://localhost:3000", "http://127.0.0.1:3000"]
'ACCESS_TOKEN_LIFETIME': timedelta(days=2),
'REFRESH_TOKEN_LIFETIME': timedelta(days=10),
# HTTPOnly Cookies
"AUTH_COOKIE": "access_token",
"AUTH_COOKIE_REFRESH": "refresh_token",
"AUTH_COOKIE_SAMESITE": "None",
"AUTH_COOKIE_SECURE": True,
"AUTH_COOKIE_HTTP_ONLY": True,
"AUTH_COOKIE_PATH": "/",
"AUTH_COOKIE_DOMAIN": None,
axios.js
import axios from "axios";
import { BASE_URL_BACK_SERVER } from "./_variables";
axios.defaults.xsrfCookieName = "csrftoken";
axios.defaults.xsrfHeaderName = "X-CSRFToken";
axios.defaults.withCredentials = true;
export const axiosInstanceBack = axios.create({
baseURL: BASE_URL_BACK_SERVER,
timeout: 5000,
headers: {
"Content-Type": "application/json",
},
});
Authenticating user working fine but the problem is when logging out user.
when it makes request for LogoutView it return 200 response.
But after redirecting in frontend again fetches current user which should be available if only user is logged in. When checked to network tab i found that request header for current user's details contain same cookies. Why is that happening? am i missing something here?
LogoutView
class LogoutView(APIView):
def post(self, request):
response = Response()
response.delete_cookie(settings.SIMPLE_JWT['AUTH_COOKIE'])
response.delete_cookie(settings.SIMPLE_JWT['AUTH_COOKIE_REFRESH'])
response.data = {
"status": "success",
"msg": "User logout successfully"
}
return response
logout Request
const logoutUser = () => {
axiosInstanceBack
.post("user/logout/", {}, { headers: { "X-CSRFToken": csrfToken } })
.then((response) => {
mutateCsrf();
setShouldFetch(false);
mutate("user/current/", null, { revalidate: false });
router.push("/login");
})
.catch((error) => console.log(error));
};

Django REST Framework Delete Method Request receives Forbidden 403

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);
});

Django JWT Auth and Vue: How to check if user is logged in in Vue?

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',
]
}

Method GET Django and Angular error 500 internal server

I'm building a basic app with login, register, etc. now i try finish the login using Django like backend and fronted with Angular, but i can't end my login because this error, when i try login with the correct credentials and redirect to new page or url show this error.
TypeError at /doctor
'list' object is not callable"in network panel"
service .ts
constructor(private http: Http, private httpClient: HttpClient) { }
private headers = new Headers({ 'Content-Type': 'application/json' });
getDoctores(): Promise<Doctor[]> {
return this.http.get(this.baseurl + '/doctor?format=json', { headers: this.headers })
.toPromise()
.then(response => response.json() as Doctor[])
}
component .ts
constructor(private dataService: dataService, public dialog: MatDialog,
private router: Router) {
this.getDoctores();
this.selectedDoctor = {
id: -1, nombreDoc: '', apellidoDoc: '', rutDoc: '', direccionDoc: ''
, telefonoDoc: '', release_date: ''
}
}
getDoctores(): void {
this.dataService
.getDoctores()
.then(doctores => this.doctores = doctores);
}
url.py
path('auth/login/', obtain_jwt_token),
path('auth/refresh-token/', refresh_jwt_token),
url(r'^doctor$', views.DoctorList.as_view()),
url(r'^doctor/(?P<pk>[0-9]+)$', views.DoctorDetail.as_view()),
view.py
class DoctorList(generics.ListCreateAPIView):
queryset = Doctor.objects.all()
serializer_class = DoctorSerializer
class DoctorDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Doctor.objects.all()
serializer_class = DoctorSerializer

$http request from AngularJS to Django

I am trying to send GET request to Django. In the script:
$http({
method: 'GET',
url: 'response/',
data: 'test=data',
}).success(function(data, status, headers, config){
console.log(data);
});
In the view response() function, if I try
def response(request):
data = json.loads(request.body)
return HttpResponse(data)
I will get 500 (INTERNAL SERVER ERROR). If I try
def response(request):
data = request.body
return HttpResponse(data)
the returned data is empty. I wonder what is happening?
do it like this:
$http({
method: 'GET',
url: 'response/',
data: $.param({
'test': 'data
})
}).success(function(data, status, headers, config){
console.log(data);
});
and use request.GET -
def response(request):
data = request.GET.get('test')
return HttpResponse(data)
We can use the code like this.
$http({
method: 'GET', url: '../../load/',
data: {'test': 'Nath'},
header: {'Content-Type': 'application/x-www-form-urlencoded'}
}).then(function (data) {
var ck = data.data;
}, function(response) { console.log("failed to load data."); });
views will be
def response(request):
data = request.GET.get('test')
return HttpResponse(data)
it worked..