I use tokens to send my images to the back-end service and I need to use tokens again to get back the images.
I have no problems on the upload aspect. The back-end receives the images with the token and is able to authenticate the user.
But, I have to check that the user who tries to get one image is the one who uploaded it.
The problem is that I have no idea how to force ckeditor to call a function or whatever that could specify to ckeditor to use hearders and to param them.
Thanks for your help ! :)
Pr0to
Related
I really need to be able to access images in my firebase storage dynamically by creating a URL. Something that would look like this:
https://firebasestorage.googleapis.com/v0/b/<bucket>.appspot.com/o/userImages%2F<userUID>2%2F<imageUID>?alt=media
I know it it would be possible since I managed to load the image in my browser. However, my concern is security.
I would need to set the rule allow read: if true; for this to work
If someone with bad intentions wanted to see users' images, would they be able to see all the images in my bucket or would they need to guess the userUID and the imageUID?
What you're asking isn't possible without custom code. Direct download URLs are not affected by Firebase security rules at all.
If you want to limit access to direct download URLs of any kind, you will need some sort of custom backend service that checks the end user's permission before delivering the content. This means you will have to create your own endpoint that serves the content of the file in Storage.
The rules don't work on the URLs. BUT the download URL has a token in it which can be generated by you or is generated by the bucket by default a UUID which is always unique.
https://firebasestorage.googleapis.com/v0/b/[bucket].appspot.com/o/userImages%2F[userUID]2%2F[imageUID]?alt=media&token=[accessToken]
I'm using Google Storage to store profile pictures of my users. I have couple of thousands pictures.
Now the pictures are being saved in a bucket like so:
data/images/profiles/USER_ID.jpg
So the URL to an image:
https://storage.cloud.google.com/data/images/profiles/USER_ID.jpg
I don't want users being able to see someone else picture by just knowing their USER_ID, and still, It has to be the USER_ID for easier search from a developer's side.
I can't use Signed URL as my users do not have a google account, and the pictures from the storage are fetched from a Mobile Application.
Is there a way to keep the file names as they are in the storage, but simple hide the path+filename from the URL?
https://storage.cloud.google.com/fc720d5c05411b03e5e2a6692f8d7d61.jpg -> points to https://storage.cloud.google.com/data/images/profiles/USER_ID.jpg
Thank You
You have several options. Here are a few:
Have users request the URL for another user from the server, then have the server decide whether or not the user is allowed to see the image. If so, have the server (which does have a service account) generate a signed URL and pass it back to the user (or redirect to it). This way, although the user may know the user ID of another user and the URL of their image, they still can't see the image unless the server agrees that this is okay.
Use Firebase Storage to manage the images, which will still store them in GCS but will give you Firebase's auth support.
Proxy the images through your app, either an app engine app or something running in GCE or GKE. This lets you hide everything about the source of the image, including the user ID, but has the downside of requiring all of the data to pass through your service.
Reexamine your requirements. "Easier search on the developer's side" may not be as important as you think, and you need to way the benefit of that vs the cost of working around it.
Another option is Google Images API available on AppEngine. You can link your Cloud Storage objects with Google Images API and use benefits of this API - secure URLs, transform and resize images using URL parameters.
You only need to prepare servingURL for every image stored in GCS and persist this serving URL (for example in Google Datastore)
ImagesService imagesService = ImagesServiceFactory.getImagesService();
ServingUrlOptions suo = ServingUrlOptions.Builder
.withGoogleStorageFileName(gcsImageObjectPath)
.secureUrl(true);
String servingUrl = imagesService.getServingUrl(suo);
I'm leveraging Firebase Authentication for downloading images from firebase storage. I'm also leveraging google API HTTP referrers for blockage by domain so that my image from firebase storage is only accessed from my website. But when I go to the network tab of my browser I can see the download URL of the image. By this, anyone can download my image and use it. What should I do so that my images are secured?
P.S: I'm using the firebase storage SDK and by following the documentation when I execute this code below
storageRef.child('images/stars.jpg').getDownloadURL().then(function(url) {
// `url` is the download URL for 'images/stars.jpg'
var img = document.getElementById('myimg');
img.src = url;
}).catch(function(error) {
// Handle any errors
});
I can see the download URL in the network tab of my browser.
You can't. When you give up access to a Cloud Storage download URL to any one, in any way, you are implicitly trusting that user to its access. They are free to share it with anyone they want. If you don't trust that user, then don't give them the URL.
If you don't like the way this works, then don't use download URLs, and allow only secure downloads via the Firebase SDK. At that point, you are trusting the user they will not take the content and upload it elsewhere and generate a URL to it.
You seem to have two options as far as I can tell. Unfortunately, they are basically one in the same effectively as you will probably have to implement both.
The first option is to revoke the access token on individual files you don't want to be allowed to download. Unfortunately, this also means that you can't display them anywhere you currently do via the URL as it breaks that link. See this answer for why that is a pain to do.
The second option is to use storage references to download them client side, but this only works if you are using Firebase SDK's in a web app and not a simple static website. I think this shouldn't expose the URL on the network tab of the browser if the app is set up correctly.
You can implement the second option without the first and the URL shouldn't be exposed, but you can't use the url anymore and have to use both options if you implement the first one... :/ meh... firebase is great, but nothing is perfect
This seems to work, I'll update if it doesn't
Edit: "However, the CORS configuration applies only to XML API requests," which one can just go to the file still.. https://cloud.google.com/storage/docs/cross-origin
GCP console >_
pencil icon > create cors.json [{"origin":["https://yourorigin1.com"],"method":["GET"],"maxAgeSeconds":3600}]
go back to shell and enter gsutil cors set cors.json gs://yourproject1.appspot.com
https://stackoverflow.com/a/58613527/11711280
Workaround:
I will make all rules resource.data.authorId, resource.data.members, etc. I need to match the request.auth.uid (or control calls in client code to non-anonymous uid's), and sign-in every user anonymously, at first. Then, uid will not be null when using a firebase initialized from our domain
I have a situation where in Firebase Storage users store their avatar to /users/{uid}.jpg
If I then use the Storage API to get the download URL and display the image, it ends up being very slow to make the first request because the download URL is not cached anywhere.
So my solution is to get the DownloadURL when the user uploads the image and store that in Firebase allowing the client image provider to automatically cache the image which speeds up loads considerably.
However, there is one problem with this solution.
If a user replaces their avatar, the old link becomes broken instead of updated. I believe this is because a new token is generated each time something is uploaded for security reasons but these are of no benefit to me.
So my question is twofold:
1) How can I allow a user to upload an avatar to a path that is dedicated to them such as /users/{uid}.jpg, get a bare download URL that can be cached by the client, and have that URL remain the same even when the file changes at /users/{uid}.jpg
2) If this is not possible, what is the normal way to solve this issue?
Download URLs are opaque. The contents of the actual URL itself is an implementation detail of the system, and it's not supported to dig around in its contents. The URLs can't be dissected or composed.
You can use a storage trigger with Cloud Functions to automatically generate a signed URL whenever something changes in your storage bucket.
So instead of serving from a hard-coded URL, simply retrieve the URL from an updated value in the datastore (or any data storage system). Every time the user updates the avatar, simply store the new URL in the datastore and you can query for it when you need it.
I have a servlet for allowing manipulations of images - zoom, etc.
What's the best way to deploy this service so that the users of the servlet keep their images confidential?
I assume this means they need to run the servlet on their own servers rather than on mine.
Is there any other way of providing this service to them?
They have to give you the image for you to transform it. You can promise that you delete it immediately afterwards, but your users will have to take your word for that.
File hosting services can maintain confidentiality by hosting only encrypted files that the service operator cannot open themselves. But you cannot manipulate an encrypted image without decrypting it first.
You can use HTTPS to make sure there are no eavesdroppers, and also make sure that you send the image to no one except the owner of the original (as far as you can tell from the login session). You should delete any files as soon as you can.
As you say, the only way to ensure that no one else gets to see the image is to run the application on the user's end.