Protecting files for users

I’m hoping someone can point me in the right direction on how to learn this …

I am uploading PDF files to Xano and storing that metadata in the table cell.

The file should be only available to certain users who have access to that specific row.

I need the user to be able to click on a link which would open another tab and display the PDF file, or download it.

If the user does not have access to that row though, they should not be able to view that file.

I tried to just respond with a file object from Xano, but that does not work.

It would be amazing if I could just have someone go to a url with the file table.row.id and it would respond with the file if they are authenticated.

I have no clue how to do this. I don’t know if I can do it with Xano. I looked at AWS and google cloud, but that stuff is way too complex.

1 Like

Nevermind. My previous response would have responded with the file URL from Xano if Authenticated, however as the file stored outside of Xano, it would have not prevented anyone to forward the direct link to someone and get the file.

Maybe take a look at Google Drive api

you can assign access to documents via API. Maybe that is easier than the other options you looked at?

Or if you dont mind (for example the downloaded pdf can be forwarded to someone too) Xano meta data actually have a URL part which if you open, it presents you with the file.

So you can do a Get request to an auth enabled endpoint in Xano that returns the row.id.column.url

image

@Edward Yes, I need to make it so that users only have access to the files that they should be allowed to have access to. This logic is based on the data in Xano. So, the public URL will not work.

I think I’m going to need to use something other than Xano, since every file in Xano has a public URL.

I just dont know how to make it so that when someone clicks a link to a file, it tests the authentication in Xano and then runs some other script to return the file to the user.

I have a solution for you. (been researching for hours as I was interested to know :smiley: )

Not elegant but works:

Get an authenticated request to your XANO endpoint that returns the relevant PDF with the Xano Storage URL. You should get: “url:…” response

Next: Add to your function stack in Xano: Get file resource as data. The input should be the URL from previous step. Result of this step should have name, size, mime, data. We will use data in next step

Next: Add to your function stack: Create variable from the previous step.Value: result.data then add filter > base64encode. This result should return a single base64 encoded string.

Last step: In weweb add a custom html in the page and bind it to javascript: Code:

var pdfLink = '<a download="myfile.pdf" href="data:application/octet-stream;base64,XANO RESPONSE HERE">Download PDF</a>'

return pdfLink

obviously change XANO RESPONSE HERE to the base64 string that comes from Xano

This will download the pdf

1 Like

Edward thank you!

This is a really good solution. The only problem is that the file at the url is still public. Although unlikely, someone could potentially visit that url and have access to the file.

I think I may be able to use AWS to store the file though, and use your solution, but just get the file from AWS, with authorization into AWS.

Only problem I see there is where to store the key in Weweb. Someone could just see it in the JavaScript.

Any idea on how to solve for that?

Is that a single key for AWS? I am not familiar with AWS, however I may have a couple of ideas, I just need to know if that is a single key or a key for each user?

If you are thinking to use: Signing and authenticating REST requests - Amazon Simple Storage Service

the process would be done in your Xano function stack which returns the file from S3 (the file name would be a variable from Xano based on your auth access logic) and then you return that to Weweb.

Yes. It’s just one key… I will use any service. Doesn’t have to be AWS. I just started playing with that

Im thinking, would you not be able to upload the image to Xano first, then forward the image to the external storage of yours, then delete original from Xano. In this case your credentials to external storage are stored in Xano function stack. Then you can retrieve the image in same way, using your credentials

Right. Basically using Xano as the backend code behind. They are actually pdfs that I need.

Can Xano send the pdf back as a file object, or a content-type/pdf or something like that so it doesn’t just come as json that can then be automatically downloaded as a file?

What I meant is this: My first solution would returned the base64 pdf which is downloaded. However you mentioned that the original Xano URL is still accessible (however I doubt anyone could guess the original Xano file URL if you only return the pdf as base64, not the link). However if you want to be super secure: I’m proposing:

Upload pdf to Xano as usual

forward pdf to external service using credentials (so noone has access to public url like in Xano, because external service needs your credentials to access file)

Store external File URL in Xano (this can be a column next to where you would have stored the original pdf

Delete PDF from Xano

When retrieving PDF:

Make the auth request to Xano that has the external pdf url that you saved earlier

with that URL get the file from external storage using your credentials

base 64 the file and pass it to weweb

Weweb downloads the file using the link as I mentioned above.

In weweb you do not actually store any URL, because the base64 part of the link comes as a variable from Xano as per the request when retrieving a file above:

var pdfLink = '<a download="myfile.pdf" href="data:application/octet-stream;base64,XANO RESPONSE HERE">Download PDF</a>'

return pdfLink

Really appreciating this thread - I did not realize that Xano links were publicly available. Thanks for your hard work thinking through a solution, @Edward

@kevinwasie, I was already looking at Uploadcare for their file uploader and security - might be a potential solution to your problems as well?

2 Likes

@Edward this makes sense. Actually, I think we can cut out the step of uploading it to Xano at all…

For my scenario, We can upload right to AWS into a non-public “bucket”, which makes it so the file cannot be accessed without authentication. The AWS endpoint will respond with the protected url.

Store that url in Xano. Then, do everything else you said to get the file inside function stack of Xano and send back to browser.

My file will be pdf, so I’m going to try out your method to send it back to weweb to be downloaded base64.

Thank you!

@kyanaloe ill check that out. I was thinking about your scenario earlier because you need hippa compliance, right?

AWS also offers url signing. It also is based on time expiration. I was trying to find a solution that would only allow one time download from url signing.

I think @edwards solution will accomplish that though.

Yes, HIPAA compliance is the goal for me. Xano offers a HIPAA Compliant add-on, but it’s unclear how that impacts file storage.

@Edwin’s solution is great

BAM!

I think this will take care of it.

I don’t think this actually provides additional security… am I missing something?

I think that the files are now not available with a url until the metadata is created on them? Maybe I’m wrong about that.

If so, then you could just decode the file from here instead of AWS