Reputation: 916
I build a API usign Django 2 and Django Rest Framework. All get methods are ok, using authentication first to receive a token and using this token to access all the other methods. The only problem is with the only function that I have that receive a POST data.
The problem is that the call for this POST method allways return, even providing the "authorization" token, this message:
"{"detail":"Authentication credentials were not provided."}
The funy thing is that in POSTMAN it works! Another developer tried with JavaScript and it allways return this message. I tried with PHP making a POST request using CURL and give the same error. Just with POSTMAN it works...
This is my Django Rest Framework settings in settings.py:
INSTALLED_APPS = [
...
'rest_framework.authtoken',
...
]
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
),
}
This is the method called trought API, in views.py:
@api_view(['POST'])
def api_inventory_sector_items_check(request, branch_id, inventory_id, sector_id):
# Do something
This is the url.py:
# ...
from rest_framework.urlpatterns import format_suffix_patterns
# ...
urlpatterns = [
...
path('.../check', # See the long URL bellow
views.api_inventory_sector_items_check,
name='app.api.inventory_sector_items_check'),
]
# ...
So I'm trying to call using POST:
{{domain}}/app/api/v1/branches/1/inventories/2/sectors/100101329/items/check
'Content-Type: application/json'
'Authorization: Token Token efad3303547374b7c035499218ad5d0cceb03178'
And in the body posting some data...
As I told before, using POSTMAN all it's ok. But when we try to submit this post by any other 'method', it returns the same message. Detail: with the same HEADER, but for GET requests, all works.
Follow a example of request using PHP that returns "... credentials were not provided".
<?php
$data = array(
"data"=>"{'id':'20012738', 'obs': '', 'resp':'325880','final':1}",
);
$data_string = json_encode($data);
$ch =
curl_init('http://localhost/app/api/v1/branches/1/
inventories/7/sectors/100162162/items/check');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string)),
'Authorization: Token efad3303547374b7c035499218ad5d0cceb03178'
);
$result = curl_exec($ch);
echo $result;
?>
Someone can help me? Thank you very much!
Upvotes: 1
Views: 4016
Reputation: 916
My PHP code to submit was wrong and Will Kelling help me. Thank you. Anyway, to submit POST data for Django Rest API was retourning no data... I solved this problem by use:
request.body
instead
request.POST.get('data')
Then, my code become like this:
@api_view(['POST'])
def api_inventory_sector_items_check(request, branch_id, inventory_id, sector_id):
try:
sector_items = request.body
except Exception:
return Response({"detail": "No data received or isn't a JSON data"}, status=status.HTTP_406_NOT_ACCEPTABLE)
try:
sector_items = json.loads(sector_items)
except json.JSONDecodeError or TypeError:
return Response({
'detail': "Data received has a wrong format. This is not a JSON var."
}, status=status.HTTP_404_BAD_REQUEST)
Upvotes: 1
Reputation: 23004
You have a subtle typo in:
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string)),
'Authorization: Token efad3303547374b7c035499218ad5d0cceb03178'
);
The array()
ends before the Authorization
header is added (note the closing parenthesis at the end of the content-length header). That will prevent the token from being transmitted correctly, and will likely cause the authentication error.
Change to:
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string),
'Authorization: Token efad3303547374b7c035499218ad5d0cceb03178')
);
Upvotes: 1