I am working on a project where I am using Django as the back end. I am working with Django rest framework, and I have an API to download a File.
@detail_route(methods=['GET'], permission_classes=[IsAuthenticated])
def test(self, request, pk=None):
try:
ticket = Ticket.objects.get(id=pk, user=request.user)
file_path = ticket.qrcode_file.path
if os.path.exists(file_path):
with open(file_path, 'rb') as fh:
response = HttpResponse(fh.read(), content_type="image/jpeg")
name = "%s %s %s %s.jpg" % (ticket.show.title, datetime.strftime(ticket.show.date_time,
"%H_%M_%p"),
datetime.strftime(ticket.show.date_time, "%d %B %Y"), ticket.id)
response['Content-Disposition'] = "attachment; filename=%s" % name.replace(" ", "_")
return response
return Response({'error': 'Ticket doest not belong to requested user.'}, status=status.HTTP_403_FORBIDDEN)
except Ticket.DoesNotExist as e:
return Response({'error': str(e)}, status=status.HTTP_404_NOT_FOUND)
On the front-end I am using Nuxtjs (ssr for vuejs). This is a little snippet of code, where a user can download the file by clicking a link of target blank.:
<a class="downloadBtn" target="_blank" :href="`${baseURL}/payments/api/tickets/${ticket.id}/download_ticket/`">Download e-ticket</a>
The web app is running on Nuxtjs server (localhost:3000) and Django server is running on localhost:8000, only the API is used to municate between the Nuxtjs and Django by using the auth token.
When I click the download link it opens up a new tab and make a request from that new tab, where no token is passed with the request. And since, the django view to download the ticket is permission_classes=[IsAuthenticated]
I cannot be authenticated as request.user
is anonymous.
Is there any other way that I can make it work to download the file by checking whether the requested user is the Ticket's owner?
I am working on a project where I am using Django as the back end. I am working with Django rest framework, and I have an API to download a File.
@detail_route(methods=['GET'], permission_classes=[IsAuthenticated])
def test(self, request, pk=None):
try:
ticket = Ticket.objects.get(id=pk, user=request.user)
file_path = ticket.qrcode_file.path
if os.path.exists(file_path):
with open(file_path, 'rb') as fh:
response = HttpResponse(fh.read(), content_type="image/jpeg")
name = "%s %s %s %s.jpg" % (ticket.show.title, datetime.strftime(ticket.show.date_time,
"%H_%M_%p"),
datetime.strftime(ticket.show.date_time, "%d %B %Y"), ticket.id)
response['Content-Disposition'] = "attachment; filename=%s" % name.replace(" ", "_")
return response
return Response({'error': 'Ticket doest not belong to requested user.'}, status=status.HTTP_403_FORBIDDEN)
except Ticket.DoesNotExist as e:
return Response({'error': str(e)}, status=status.HTTP_404_NOT_FOUND)
On the front-end I am using Nuxtjs (ssr for vuejs). This is a little snippet of code, where a user can download the file by clicking a link of target blank.:
<a class="downloadBtn" target="_blank" :href="`${baseURL}/payments/api/tickets/${ticket.id}/download_ticket/`">Download e-ticket</a>
The web app is running on Nuxtjs server (localhost:3000) and Django server is running on localhost:8000, only the API is used to municate between the Nuxtjs and Django by using the auth token.
When I click the download link it opens up a new tab and make a request from that new tab, where no token is passed with the request. And since, the django view to download the ticket is permission_classes=[IsAuthenticated]
I cannot be authenticated as request.user
is anonymous.
Is there any other way that I can make it work to download the file by checking whether the requested user is the Ticket's owner?
Share Improve this question asked Mar 10, 2018 at 10:38 AamuAamu 3,6118 gold badges45 silver badges62 bronze badges 4-
does removing
target="_blank"
help ? I think the token is not being passed because the link is getting opened in a new tab, not sure though. – Chintan Joshi Commented Mar 13, 2018 at 8:49 - What kind of Authentication are you using Session or Token? – Igor Yalovoy Commented Mar 13, 2018 at 10:32
-
@ChintanJoshi Nope. Removing
target="_blank"
doesn't help. – Aamu Commented Mar 13, 2018 at 17:45 - @IgorYalovoy I am using Token authentication (jwt). – Aamu Commented Mar 13, 2018 at 17:45
1 Answer
Reset to default 9 +25Because you are using JWT, you should download the file from your frontend after requesting it from your api using some sort of ajax request
and the JWT header.
some_api_request_hendler().then(function (response) {
var file = new Blob([response.data], {type: response.headers("Content-Type")});
var link = document.createElement('a');
link.href = window.URL.createObjectURL(pdf);
link.download = "the_new_file_name";
link.click();
});
I'm using this answer as an example. Your API should not be changed. The way you did it is the way to go.
And your link now need to call your new frontend function instead of just <a href
.
Edit:
I asked a question like that a few years ago. You might find some help there.
Browser Compatibility
blob, createElement, createObjectURL