I want to implement a CSV export from Shopware 6 admin. I have a button, want to open a new window and get a CSV file.
I implemented a controller:
/**
* @Route(
* "/api/winkelwagen/export/csv/{id}",
* methods={"GET"},
* defaults={"auth_required"=true, "_routeScope"={"api"}}
* )
*/
public function export(string $id, Context $context, Request $request): Response
{
/** @var PromotionEntity $promo */
$response->setContent('csv file');
return $response;
}
But to call this controller, you need to be logged in which totally make sense.
My button in the administration currently opens a new window and opens the page:
window.open('http://www.fabian-blechschmidt.de', '_blank');
Which of course doesn't work with the api url, because you needs to be authenticated.
So my question is: How do I implement this authentication and get a CSV file in the backend? :-)
Maybe my approach is totally broken - happy to get a better idea!
I would not recommend to create a link with a data object on the fly using URL.createObjectURL
as written in other answers. I believe this can create issues with large downloads (but I mostly assume).
I would suggest to do it like the core does it and use an access token.
See here in the export download in the core:
The URL is build like this:
return `/${baseUrl}/_action/${this.getApiBasePath()}
/file/download?fileId=${fileId}&accessToken=${accessToken}`;
So this is a secure way, does not reinvent the wheel and avoids the need to create some blobs on the fly.
If you enter the follow the code entry here:
Download Controller -> passes the token to the download service
you can see that the token is generated specifically for the file.
But I see no reason why the general admin-access token should not be used to create such short-lived download URLs.