views:

66

answers:

3

On a actual project (dating site) i have the following scenario:

Member can upload photos (main profile) and create albums and assign photos to it. Now the member can choose only to allow registered members, premium members or members in his favorites to access the album.

The easiest solution is to hide the album, but if someone who has access post the src url to the photo it would be accessible to everyone who has the url.

I see flickr and facebook secure them in a good way, but how i can implement that without to need to query many times the DB and replicate the user auth/session. The photos will be stored on a own server (varnish/nginx).

Has anyone a idea how this can be done in mind of high traffic and to use less resources as possible?

The solutions needs to can handle the actual 20m members and around 30m photos.

A: 

The best solution is to store the image outside the web accessible part of your server. Then, instead of referencing the photo directly, you would reference a php page pointing to the image as so:

http://www.example.com/image.php?imageid=1234567

Then in your php script, you can check if the logged in user has access to the photo, and if so, you stream the image out to the user in the response.

Kibbee
That much the QA understands already. He's asking how to optimize that.
Developer Art
@Kibee - This way it takes too much resources and is not usable for us. The idea would be to be able to handle the auth on the photo server with use of some secure-key and/or some information stored by memcached but i don't figure out how flickr/facebook do this exactly.
Nenad
If you can access the photo without looking at the actual PHP session info, then there is no way to stop the user from grabbing the URL and posting it somewhere else. From looking at facebook, it looks as though they just use a really long unguessable URL for each photo. If you take a photo URL from facebook, and post it into a browser you aren't logged into facebook with, you can still access the photo.
Kibbee
@Kibbee - I have think facebook has some security implemented that this can not be done i was wrong, but Flickr and other Image hosting sites has some solution implemented for photos who have limited access rights, the question is only how they have do that :-)
Nenad
A: 

As an idea...

You could create a mapping table where you "prepare" the access permissions for pairs user->photo based on favorites, friends etc.

Then you return the images based on these permissions but cached per user. This will lower the stress on your servers but there will be some delay in applying restrictions due to cache timeouts.

Developer Art
The problem will be the handling, if I understand correct you would store the information between user and access to every photo object, this would result in many records (the site has 20m members and 30m photos) which makes it hard to update and to store.
Nenad
Ok, drop this part then. The hint is to cache the image results but vary caching by users. That is if your framework supports this.
Developer Art
Still I see that way a usage of too much resources. We use a custom framework for this project so we can adapt it completly to our needs.
Nenad
+2  A: 

Well, one possibility would be to run something like Lighttpd's mod_secdownload.

Basically you set a "secret" string in the configuration section. Then when you generate the links, instead of making a link to the resource, it's a temporal link (so it's only valid for $x number of seconds). That way the user needs to visit the page again (and hence pass access control again) before being allowed to view that image...

Apache has a similar module: mod_auth_token...

ircmaxell
ircmaxell - This solution i will take in mind, I hope it will work for photos who we show inline with img src tag.
Nenad
It should. If the time has past, it'll simply return either a 403 Forbidden (If the token is invalid), a 410 Gone if the timeout is reached or a 404 if there's no file... So it *should* help for your specific case... And yes, the generated url can be used directly in the image tag. It'll resolve the same way as `/path/to/image.gif` with the same headers. The only difference is that the URL will expire after a certain time...
ircmaxell
I will try some test with this solution i saw nginx provide smiliar functionality with ngx_http_secure_download_module now I hope there is not a big performance lost using it. The only problem i saw is that nginx ask for a folder for secured stuff because we all files store in same structure I don't see actually a solution how to use it. The member need to can change the permissions how they want on the web app and it would be not possible to do any move of files on the photo storage server.
Nenad
Great answer, nice to know this stuff.
Alix Axel