I have the same problem. Currently I found 2 ways:
1) base64_encode() + ajax + js/jquery
- Store every image encoded by base64_encode() in binary file or database OUTSIDE www folder.
- Use ajax to get that data. it should return "data:image/jpeg;base64,$enc_imgbinary"
- Replace 'src' of 'img' attribute with returned result using js/jquery
pros
- impossible to access image with direct link
cons
- I did found not similar solution for video.
- images should be encoded beforehand (or first usage) to minimize server CPU usage.
- encoded images takes about 30% more space on disk => 1.3x disk space
- if you want to keep original images on server => 2.3x disk space.
- ~30% more data will be send over the network
2) long-random-names (+symlinks)
A) Store images in www folder using long-random names
B) Store images outside www folder with symlinks to www folder.
(images outside www can also work as your desktop images backup)
notes:
pros:
- Can be used for video also
- You can still keep original images with original names outside www folder by creating symlinks to www folder using long-random-names. Even different for every user.
- Image can be used outside your server (in forums, quick send direct link to your friend or similar)
cons
- symlinks must be created beforehand (or on-fly)
- Image can be accessed with direct link
- however its nearly imposible to guess it
- also you can change symlink random-name periodicaly or on image rights change (I quess google+ does so)
- map original-name → long-random-name should be stored in db (or sidecard/meta file)
- (can be bypassed if you keep original-name inside long-random-name by encoding/decoding or by combining original-name + long-random-name)
=====================================
I had implemented case 1) and it worked for me fine, however I did not found similar solution for HTML5 video.
Case 2) seems more flexible. However I still not sure about security.
If anyone sees security holes please let me know.