📜 ⬆️ ⬇️

Ways to delimit file access with php + mysql + apache

The task of delimiting access to files that are stored on the disk is quite rare, but it can arise when writing: an online store that sells files or a file server like rapidshare.de. In this article, I will discuss the 3 ways of access control using php, mysql, and special modules of the apache web server.


Method # 1: use symbolic links

This is the easiest way in my opinion, it does not require installation of any additional apache modules, but at the same time, in its pure form, it is the least flexible method and it will work only on a server running * nix. However, this method is perfect for file hosting.
What should be done:
1. Create two directories, in one of which all files will be stored, access to which must be restricted, and the second will be empty for the time being. For example, I created the following directories: members and free;
')
2. In the members directory we will create a .htaccess file with one “deny from all” directive, so we close this directory and all the files that are located;

3. For example, create a file in the members directory test.html. If you access this file via http, we get Forbidden, i.e. the user even having a direct link to this file will not be able to download it;

4. Now suppose that the user has logged in to your site or performed any other actions, after which he can get access to the closed file. To give it access, all that is needed is to create a symbolic link to this file in a directory that is not closed with .htaccess. In my case it will look something like this:
exec('cd free; ln -s ../members/test.html test.html');
thus, in the free directory we will have a link to the file from the members directory and we will be able to redirect the user to it or issue a URL.

It is also possible and necessary to add some hash and time to which it will be active to the name of a symbolic link. To remove expired links, you can simply write a CLI script and execute it on the crown once every N minutes.

Method # 2: use the mod_auth_mysql module

This module allows you to implement user authorization when trying to download a file from a closed .htaccess directory. User search is performed in MySQL table. Download the latest version of the module and get acquainted with the documentation here .
Consider the work of this module on the same example as in method # 1 , but now we will only have the members directory.
What should be done:

1. Most likely in the database of your site there is already a table in which the list of registered users of the site is stored, in which case you will need to add a field to this table in which you will store md5 password hashes (unless of course you don’t already store them) . But since I don't have all this, then I will create a table from scratch:
CREATE TABLE users (
id int(11) unsigned not null auto_increment primary key,
login CHAR(50) NOT NULL,
password CHAR(50) NOT NULL,
unique key login_idx (login)
)

As can be seen from the table structure, the login field must be unique and must not contain a NULL value;

2. In the membert directory, edit the .htaccess file and write the following into it:
AuthName "Need authorization" #
AuthType Basic #
AuthMySQLHost <mysql_database_host> # MySQL
AuthMySQLUser <mysql_database_user> # MySQL
AuthMySQLPassword <mysql_database_password> # MySQL
AuthMySQLDB <mysql_database_name> # MySQL
AuthMySQLUserTable users # ,
AuthMySQLNameField login #
AuthMySQLPasswordField password # md5
AuthMySQLPwEncryption md5 # ,
AuthMySQLEnable On #
require valid-user # , ..


3. We request the file from a closed directory. This can be done in two ways:
3.1 Just by giving the URL to the desired file, for example, example.com/members/test.html - in this case, the user will see a dialog box asking to enter a login and password. This method is not very convenient, especially when it comes to access to a large list of small files, such as viewing a photo gallery;
3.2 Login and password can be added directly to the file URL, for example:
test_login : test_password@example.com/members/test.html - in this case, if the username and password are correct, the user will immediately get access to the file. If no match is found, a dialog box will be displayed, as in the first version. For obvious reasons, this method does not look very attractive due to security concerns. This problem can be partially solved by replacing the string “AuthMySQLPwEncryption md5” with “AuthMySQLPwEncryption none” in .hataccess. In this case, in the URL instead of the password, you need to add its md5 hash, for example: test_login : test_password_hash@example.com/members/test.html

Method # 3: use the mod_auth_cookie_mysql module

This module is very similar in its functionality to the mod_auth_mysql module. But even so, this module has 2 significant differences:
1. He can take information for authorization from the user's cookie;
2. The user login / password does not appear in the cookie, which negates the possibility of their being stolen.
Download the module and get acquainted with its documentation here .

What should be done:
1. Create a table in our MySQL database:
CREATE TABLE `users_sessions` (
`cookie_name` varchar(32) NOT NULL,
`cookie_value` varchar(32) NOT NULL,
`expire` int(11) default '0',
`ip` varchar(15) NOT NULL,
`login` varchar(32) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

where: cookie_name is the cookie name, cookie_value is the cookie value, expire is the expiration time of the cookie in unix timestamp format (in php, the current time in this format is returned by the time () function), ip is the remote IP from which the user logged in, login - login current user (needed to create personal .htaccess files).

2. In the members directory, edit the .htaccess file by replacing its contents with the following:
# , "Cookie"
AuthType Cookie

# mod_auth_cookie_mysql
AuthCookieSql on

#
AuthCookieSql_DBhost <mysql_database_host>
AuthCookieSql_DBuser <mysql_database_user>
AuthCookieSql_DBpassword <mysql_database_password>
AuthCookieSql_DBName <mysql_database_name>

# , .
AuthCookieSql_DBtable users_sessions

# .
AuthCookieSql_SessnameField cookie_name
AuthCookieSql_SessvalField cookie_value
AuthCookieSql_UsernameField login

# cookie , .
# ,
# cookie
AuthCookieSql_CookieName AuthorizationCookie

# , cookie.
# , .
AuthCookieSql_ExpiryField expire

# , IP .
# , IP .
CookieAuth_RemoteIPField ip

#
require valid-user


3. After successful authorization of the user on the site, we will do the following:

// cookie
$expire = time() + 60 * 60; // cookie 1

// cookie
$cookieValue = md5($userPassword . $userLogin . $expire . $_SERVER['REMOTE_ADDR']);

// cookie
setcookie('AuthorizationCookie', $cookieValue);

// cookie
mysql_query('insert into users_sessions values ("AuthorizationCookie", "' . $cookieValue . '", ' . $expire . ', "' . $_SERVER['REMOTE_ADDR'] . '", "' . $userLogin . '")');


After these actions, we can redirect the user to any file in the members directory.

That's all. At the moment, these are all methods of differentiating access rights to files managed by the apache web server that I know. If someone knows others - share the link and I will read about them with pleasure.

Source: https://habr.com/ru/post/81575/


All Articles