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 communicate 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?
Because 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With