How to get files from a public share via OCS Share API without credentials

Hey folks.

Quick question.

On my website, there’s a gallery which shows some photos. Currently those photos are located on my webserver, which isn’t comfortable at all.

Therefore I had the idea to just get the photos for the gallery from my NextCloud, which is already running and in use. I quickly found the OCS Share API. So I tried getting a sample public share by making a GET request to /ocs/v2.php/apps/files_sharing/api/v1/shares/SHARE_ID. Unfortunately this gives me a 401 response.
So I checked how to log in via the OCS API, but as far as I can see, you have to open a login webview on the client so they can authenticate themselves. But this is obviously not what I want because I just want to get a list of all files in the shared folder, which is public anyways, so I can load them in my gallery. All without prompting my website visitor to do any login.

So I’m wondering, is there another way to get public shares from NextCloud? I’m sure there has to be some way, right?

If this doesn’t work due to technical limitations, I’ll have to scrape the share via JS fetch, but that’s definetly not the proper way of doing things.

Thanks in advance everyone!

I don’t know if you can use this in your setup, but I just recently found out how to upload and download files from a public share with curl. You can also mount it with WebDAV and perhaps use the files in your web server that way.

Where $sharetoken is the long string at the end of the share URL, $sharepwd is the share password, and {} is the file name. Use -T for upload and -o for download.

Hi and thanks for your response.

While I could implement curl in JS, this still would require me to edit my websites code everytime I want to change the photos, because I have to add all the filenames.
What I want is a dynamic solution, something that gives me a list of all the files in the share, so that I can just upload photos to that share in NextClouds web interface without ever having to touch the websites code.

What if you mounted the share with WebDAV somewhere under your web root? Then the files would just be accessible in a subfolder. Sorry, I don’t know JS.

That approach is interesting :thinking:

But there’s a downside to this. Since JS is a client side script, I can’t just query all the files in a specific folder on the webserver. I would have to create something like an internal API which tells my frontend where the files in the webroot are located and what there names are.
I’ll keep this in mind as a backup solution, but it isn’t a good one.

@staff But there has to be a way to use NextCloud’s API to just get files from a public share, doesn’t it? in my opinion it doesn’t make any sense to force the client to authenticate if the share that’s beeing requested is public anyways. I’d expect the /ocs/v2.php/apps/files_sharing/api/v1/shares/ endpoint to not require any credentials as long as the given share was made public.
I think my usecase, which is using NextCloud as a CDN for my websites gallery, is something a lot of poeple could benefit from. Why should I upload my photos to my website if they already are stored on my NC? Would make sense to me to just get a list of links to the photos inside of a share.

https://example.com/nextcloud/public.php/webdav is a general webdav endpoint.

Of course you can also query which files are in that public share by using PROPFIND. See the docs: Basic APIs — Nextcloud latest Developer Manual latest documentation

Thanks so much @marcelklehr!

I can query all files in the public folder “website” with my user “website”. The Request looks something like this: https://cloud.example.com/remote.php/dav/files/website/website

The response for each image in the folder (sanitized & shortened) looks like this:

<d:response>
	<d:href>/remote.php/dav/files/website/website/293A8324.jpg</d:href>
	<d:propstat>
		<d:prop>
			<d:getlastmodified>Sat, 09 Jul 2022 14:41:47 GMT</d:getlastmodified>
			<d:getcontentlength>1218515</d:getcontentlength>
			<d:resourcetype/>
			<d:getetag>&quot;8aecb51e4916ef3f7321cc6f8b4fd0ec&quot;</d:getetag>
			<d:getcontenttype>image/jpeg</d:getcontenttype>
		</d:prop>
		<d:status>HTTP/1.1 200 OK</d:status>
	</d:propstat>
	<d:propstat>
		<d:prop>
			<d:quota-used-bytes/>
			<d:quota-available-bytes/>
		</d:prop>
		<d:status>HTTP/1.1 404 Not Found</d:status>
	</d:propstat>
</d:response>

I’m than extracting the file names from the href attribute to put them into an array which I than iterate over using the https://cloud.example.com/remote.php/dav/files/website/website/FILENAME endpoint to finally get all the images.

It isn’t as easy as I’d like it to be, but it works, so I won’t start complaining :smile:

Thanks a lot!