-1

I have an interesting dilemma... I am hosting several .mp4 files on a WAMP server. I am well aware of the method of storing files outside of the document root and using a PHP script to authenticate a user before retrieving the file contents. However, these .mp4 files are required to be inside the document root. Is there any way that I can authenticate a user who is trying to directly access one of these files? I have tried a .htaccess rewrite that takes a requested URL ending in ".mp4" and redirects to a PHP script passing the requested file as a parameter, but of course this just loops.

This is the rewrite rule in the .htaccess file...

RewriteEngine on
RewriteRule ^(.*).mp4$ /media/auth.php?file=$1.mp4

The idea was, a user will try to access http://www.example.com/media/myVideo.mp4, this reuest would get routed to a PHP script (auth.php) that would pick up the requested file from the URL using $_GET['file'], it would authenticate the user using a $_SESSION variable, and then user a header('Location: ' . $file) to send the authenticated user to the actual file. Again, I realized quickly after implementing this that it would just loop...

Any help would be greatly appreciated. Thanks!

Here's why they cannot be outside the doc root...

@IdontDownVote, very complicated, but I'll attempt a short version... I have this MOSTLY working great with files outside the doc root, with one serious issue. When I access the files using the PHP script, I am able to view the video in the Chrome browser, play, pause, rewind, the whole deal. The only (big) problem is when I use this method, I am not able to Cast the video. When I access a .mp4 file directly, it gives me the option to Download or Cast, but using the PHP script, only the Download option is available. Believe me, I have tried everything including discussing with two Google developers. I posted on Stack Overflow about this issue here with no joy...

Why can't I cast an MP4 file served by PHP from outside of the document root?

I am not sure why this is getting downvoted, this is causing my a lot of headache and I am just looking for advice...

Justin T.
  • 826
  • 1
  • 5
  • 13
  • 1
    "However, these .mp4 files are required to be inside the document root." why? –  Oct 25 '18 at 02:04
  • `Deny from all` and `Allow from all` in `.htaccess` - Deny access to everything in a directory, then allow access to `index.php` where you can serve the file from if you want. – ArtisticPhoenix Oct 25 '18 at 02:07
  • As long as your PHP script returns the appropriate `Content-type` and `Content-length` headers, your browser should not be able to tell the difference between a direct link to a file and one marshalled by PHP. – Phil Oct 25 '18 at 02:10
  • 1
    You can also use `BasicAuth` in the htaccess and then provide the password via the URL `http://user:pass@somedomain/path/to/video.mp4` – ArtisticPhoenix Oct 25 '18 at 02:11
  • sounds like your script is sending the wrong headers, you should be asking about that; rather than this 'work-around' –  Oct 25 '18 at 02:21
  • @IdontDownVote, this is what I have spent days perfecting, the headers are LITERALLY IDENTICAL to the castable option. That is the help I was asking for in my other post (see edited question). I was sure it had to do with headers as well, but I went to great lengths to make them identical and it still failed to cast. – Justin T. Oct 25 '18 at 02:24
  • @JustinT. I've found a duplicate question for you and I suggest you give the provided solutions a try. If it doesn't work, please update your question with what you tried and explain how it didn't work and send me a comment here so I can re-open your question. – Phil Oct 25 '18 at 02:31

1 Answers1

1

First off have you tested it when serving the file though PHP outside of the document root?

When I access a .mp4 file directly, it gives me the option to Download or Cast, but using the PHP script

If you can then you can simply block access to all but one PHP file and use that to dish it out (you could allow access to *.php too..

#.htaccess
Order Deny,Allow
Deny from all

<Files index.php>
Allow from all
</Files>

That will only allow index.php to be accessed in whatever folder (and sub-folders) the htacccese is put in. This might be better if you have a existing login system in PHP that you want to make use of for your users.

If you can't then the only way I can thing of is to try using BasicAuth, and Htaccess like this:

#.htaccess
Order Deny,Allow
Deny from all

AuthType Basic
AuthName "Admin Only"
AuthUserFile /pathto/.htpasswrd
require valid-user

Allow from all

Then in a file named .htpasswrd put some stuff like this:

admin:$apr1$o48wfurr$5WaWCjD85kBu/ydGKsQeq/

You can use something like this to hash the password.

http://www.htaccesstools.com/htpasswd-generator/

Then when you give Chrome the url, you'll have to include the user:pass@ part to bypass the login.

http://user:pass@somedomain/path/to/video.mp4

If you wan't to tie this into an existing login, you'll have to create some system to sync the passwords in the htpasswrd file to those of your users. That really shouldn't be too hard. I made one to sync our site users accounts to sFTP server, that was a real pain because of security and we have 3 sFTP servers (legacy, normal and dev). Anyway you just basically have to keep a list of their user/password and then update the file when a user is created/deleted or changes their password.

Maybe it will work (I honestly don't know ... lol).

Worth a shot.

ArtisticPhoenix
  • 21,464
  • 2
  • 24
  • 38
  • I get the feeling that since OP is using PHP, their _"authenticated users"_ come from a DB. I could be wrong though and that [doesn't necessarily rule out using HTTP Basic Auth](https://httpd.apache.org/docs/2.4/mod/mod_authn_dbd.html) – Phil Oct 25 '18 at 02:17
  • It's the only way I can think of to get past the "bug" they describe, because then PHP is not serving the file. `When I access a .mp4 file directly, it gives me the option to Download or Cast, but using the PHP script` – ArtisticPhoenix Oct 25 '18 at 02:19
  • 1
    To me, that just says their response headers are incorrect. It should be easy for OP to compare the two responses to see what they're missing (which is exactly what [the answer on their other questions](https://stackoverflow.com/a/52939403/283366) says) – Phil Oct 25 '18 at 02:20
  • Oh, I didn't look at it. I never do anything with video mostly I do backend programing and stuff like that.... So I don't even know how to cast a video .. ha ha. I used htpassword and htaccess to lock down many a old Joomla or Wordpress site.... (don't ask, not my sites ... makes it hard for the script kiddies to hack them when all they can access is index.php) – ArtisticPhoenix Oct 25 '18 at 02:28
  • @Phil, you are right, it was easy to compare the headers from the two methods. I have done this, and spent days making sure the headers are ABSOLUTELY IDENTICAL. If you really want a screenshot, I can do that lol. I was convinced it was a header issue, but I have exhausted every avenue with the headers. – Justin T. Oct 25 '18 at 02:29
  • @JustinT. I recommend using a diff tool or even a hex editor. The number of times I've been caught out by missing quotes and upper / lower case differences has taught be valuable lessons :) – Phil Oct 25 '18 at 02:33
  • 1
    You could just hash them both with MD5 and check in php (ha ha). I hash everything... really. – ArtisticPhoenix Oct 25 '18 at 02:40
  • @ArtisticPhoenix, thank you so much for the direction! Even though your advice took me down a much different path, I was able to use HTTP Basic Auth to achieve what I needed. Thanks again! – Justin T. Oct 25 '18 at 19:55
  • @JustinT. - Awesome, glad I was able to help. – ArtisticPhoenix Oct 25 '18 at 21:33