Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Downloading/streaming files from JS frontend #148

Open
jaroel opened this issue Oct 19, 2016 · 13 comments
Open

Downloading/streaming files from JS frontend #148

jaroel opened this issue Oct 19, 2016 · 13 comments

Comments

@jaroel
Copy link
Member

jaroel commented Oct 19, 2016

Hi,
We're building our support system in react using plone.restapi. Now we need to stream large blobs from the backend to the end user.
Say I've got a PDF on /Plone/orgs/projecta/specs/specs_v23_final4.pdf . How would I go about in linking to that file?

I cannot embed the users JWT token in the url, as the enduser will share that link.
And please do not say "encode the file as base64/data uri". The file can be several GBs in size. :)

I could create a route /stream_blob, which acts as a proxy I guess?

@buchi
Copy link
Member

buchi commented Oct 21, 2016

I think the question here is not specific about downloading files but how to handle links to the backend that need authentication.

The simplest way is as you propose to create a proxy in the frontend and to not have links to the backend at all. Although downloading directly from the backend would be more efficient.

The other option would be to redirect to the frontend's login page. This is something that could be done in the JWT PAS plugin.

@jaroel
Copy link
Member Author

jaroel commented Oct 22, 2016

True dat. We're going to try the proxy stuff.

@tisto
Copy link
Member

tisto commented Nov 26, 2016

@jaroel closing the ticket now. Feel free to re-open if you do not agree.

@tisto
Copy link
Member

tisto commented Nov 30, 2017

Adding @sneridagh's comment from #452 here:

Impossible to retrieve private images and files from standard GET contents using the token auth

Given an standard GET content from a file or image, it returns a download property with the URL of the API server e.g.:

content-type: "image/jpeg",
"download": "https://server/the-image/@@images/image",
...

but accessing to the image by the browser itself throws a 401, since the resource should be accessed with the token header. You can workarround this by making the request via JS, but it feels highly cumbersome.

@wesleybl
Copy link
Member

wesleybl commented Sep 1, 2022

@tisto @sneridagh

When an authenticated user makes requests to URLs like:

https://server/the-image/@@images/image

an auth_token cookie is sent. Why is this not enough to get a private image?

@sneridagh
Copy link
Member

If the API server is under the same URL, you can. In fact, I think it's the case with the latests additions to p.restapi. (I'll have to double check). But, you'll need to have the API server public too (and so the classic UI). The recommended way is to expose only the ++api++ traversal, as it has a lot of advantages and they are a lot of deployment scenarios where the first premise is not true.

Also, by using the proxy your app is only using own server resources and it's easy to manage and to work with, as they are all flattened to one URL (the Volto/NodeJS server one). Also, you'll be relying on two means of authentication, the token one (for RESTAPI calls) and another for images/files/any downloadable resource coming from the backend, being both have to be sync'd.

One could argue that the API calls (albeit the latest additions in matter of auth to p.restapi) also can be driven by a cookie, but it misses absolutely the point of the REST auth decoupling.

@wesleybl
Copy link
Member

wesleybl commented Sep 3, 2022

If the API server is under the same URL, you can.

@sneridagh I found a situation where, even though the api and the Volto are in the URL, this is not possible. I made the following configuration:

  • I have an nginx that receives all requests.
  • If it has /++api++ in the URL, it redirects to Plone.
  • If it has @@download or @@images in the URL, it also redirects to Plone.
  • Other URLs are directed to Volto.

When we authenticate to Volto for the first time, two cookies are created. auth_token and __ac. In this situation, private images in the format:

https://server/the-image/@@images/image

can be accessed by the authenticated user. As stated above, the request to this image will be made directly in Plone.

If I close the browser, without clicking in Volto exit button, and open the browser again, the auth_token cookie will still be in the browser and the __ac cookie will no longer be. That is, the auth_token cookie has a time validity and the __ac cookie is valid only until we close the browser.

In this situation, we are still authenticated since we still have the auth_token cookie. However, we are no longer able to access images with the above format. That is, we were only able to access it before, because of the __ac cookie.

To avoid this situation, I redirected the @@download and @@images URLs to Volto. So now the user can access them, even when we only have the auth_token cookie.

So my question is. Why can't we access them, going straight to Plone, when we only have the auth_token cookie?

@sneridagh
Copy link
Member

@wesleybl As you describe, the presence of the old __ac cookie is the reason why now the API request might get authenticated using a cookie, and these are the changes I was mentioning (implemented by Ross Patterson).

The purpose of auth_token is to be used only but Volto. It was never intended to merge both or that Volto authenticates through this cookie (or through __ac). The auth_token is a mean to persist the user token through reloads/sessions whenever is required, not to auth with a cookie. This does not mean that it does work (under some special circumstances, that were completely not intended). We never had the intention to merge them or get back to a cookie only solution for Volto, because as I said in my last comment it completely misses the point of the REST auth decoupling.

As said before, I'd try to stick to the recommended way of work with Volto, which I think it does work in every circumstance if used Volto alone and it's battle tested during the last 5 years.

@wesleybl
Copy link
Member

wesleybl commented Sep 3, 2022

@sneridagh the fact is that requests to ++api++ "understand" the auth_token cookie and requests to other URLs do not. When I sent the @@images URL to Volto, I somehow managed to get the private image. So I'm assuming that Volto has extracted the token from the cookie and put it in the Authorization header. Would it be this?

@wesleybl
Copy link
Member

wesleybl commented Sep 3, 2022

@wesleybl
Copy link
Member

wesleybl commented Sep 3, 2022

the fact is that requests to ++api++ "understand" the auth_token cookie and requests to other URLs do not.

So it's not Plone that understands the cookie auth_token for ++api++ requests but Volto that adds the Authorization header to the request. Whereas URLs like @@images do not have the Authorization header in the request. Probably because the request is made by HTML. Now I'm starting to understand. There really isn't much to do, right?

@wesleybl
Copy link
Member

wesleybl commented Sep 6, 2022

@rpatterson your PR #1303 solves the __ac and auth_token cookies out of sync problem that I described in #148 (comment) ?

@mauritsvanrees
Copy link
Member

There are lots of Volto sites, that presumably have no problem here, so I will remove the "blocker" tag (I am going through this list). Feel free to argue otherwise if you think this is a blocker that should hold up a final release or release candidate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants