Pradeep Rajvanshi
Pradeep Rajvanshi

Reputation: 115

How to restrict access to files in a folder in codeigniter

I have used CodeIgniter to develop my website but when my website is searched in Google, Google shows links to the files (pdf) in a particular folder and user can view these files (pdf) directly without login. I want to restrict google to directly show the links to these files. ex: www.mywebsite/myfolder/myfile

Please guide me how can I accomplish this.

Upvotes: 6

Views: 11091

Answers (3)

Jerry Sam
Jerry Sam

Reputation: 111

Just add below code before readfile($file). This will help browser to read image and video files.

ob_clean();
flush();

Full example

if($this->user->logged_in())
{
    if (file_exists($file))
    {
        header('Content-Description: File Transfer');
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename='.basename($file));
        header('Content-Transfer-Encoding: binary');
        header('Expires: 0');
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Pragma: public');
        header('Content-Length: '.filesize($file));
        ob_clean();
        flush();
        readfile($file);
        exit;
    }
}

Upvotes: 0

Arjun Raj
Arjun Raj

Reputation: 984

A little modification from the previous answer :

Place the .htaccess in your file folder with the content

order deny, allow
deny from all

This will deny all access to that particular folder.

For accessing the files write a function in controller with body -

public function index($file_name){
    if($this->login())  // login check
        if (preg_match('^[A-Za-z0-9]{2,32}+[.]{1}[A-Za-z]{3,4}$^', $file_name)) // validation
            {
            $file = 'my_path/'.$file_name;
            if (file_exists($file)) // check the file is existing 
                {
                header('Content-Type: '.get_mime_by_extension($file));
                readfile($file);
                }
            else show_404()
            }
    else    show_404();
}

then you have to add some line to your routes.php file in your config folder as like this

$route['my_files/(:any)'] = "my_controller/index/$1";

this will redirect all request to myfiles/bla_bla_bla to my_controller/index/bla_bla_bla

think this may help :)

Upvotes: 7

Laurence
Laurence

Reputation: 60038

Basically you need to host the files outside of the public_html folder - and instead serve them up to users via php readfile().

Something like this would work

function user_files($file_name = "")
{
    // Check if user is logged in
    if($this->user->logged_in())
        {   
            // Now check the filename is only made up of letters and numbers
            // this helps prevent against file transversal attacks
            if (preg_match('^[A-Za-z0-9]{2,32}+[.]{1}[A-Za-z]{3,4}$^', $file_name)))
            {
                // Rewrite the request to the path on my server 
                $file = '../my_folder/'.$file_name;

                // Now check if file exists
                if (file_exists($file))
                {
                   // Serve the file
                   header('Content-Type: '.get_mime_by_extension($file));
                   readfile($file);
               }
            }
        }
    }
}

Note: you need to be careful of directory transversing - so you should put in some checks that the filename is only made up of letters

Upvotes: 0

Related Questions