چهارشنبه ۰۸ بهمن ۱۴۰۴

Wednesday, January 28, 2026 GMT +3:30

محدود کردن لینک دانلود مستقیم فایل ها با PHP و htaccess

php-htaccess-download

همان طور که می دانیم، لینک دانلود یک فایل در وب به طور کلی به دو دسته مستقیم و غیر مستقیم تقسیم می شود، منظور از لینک های مستقیم مواردی هستند که عموما به فرمت فایل مورد نظر (به فرض zip.) ختم شده و با کلیک بر روی آنها یا وارد کردن آدرس در مرورگر، بلافاصله برای دانلود ارائه می شوند، قاعدتا تعریف و استفاده از این نوع لینک ها خیلی سخت و پیچیده نیست، اما مشکل اکثر مدیران سایت های مختلف که عمدتا نیاز به محدود کردن دانلود فایل ها یا دانلود با پرداخت هزینه و... دارند، ایجاد و مدیریت نوع دوم از لینک ها یعنی لینک های دانلود غیر مستقیم است، در این حالت کاربر با وارد کردن آدرس لینک در مرورگر (در پس زمینه و در سرور) به صفحه دیگری ارجاع داده شده و به طور مثال ابتدا وضعیت عضویت یا پرداخت هزینه دانلود لینک بررسی و سپس مجوز دسترسی (یا عدم دسترسی) به او داده می شود، از این رو در این مطلب قصد داریم نحوه انجام این کار را با استفاده از PHP و htaccess آموزش دهیم، به این امید که مفید واقع شود.

دستور htaccess برای جلوگیری از دانلود مستقیم


اگر با فایل htaccess. آشنا باشید، می دانید که با استفاده از آن می توان تنظیمات متفاوتی در سرورهای لینوکس و ویندوز (در صورت پیکره بندی مناسب) اعمال کرد که یکی از این تنظیمات، بررسی لینک درخواستی و محدود کردن حالت دانلود مستقیم آن است، در این شیوه در مرحله اول دستوری در htaccess، با استفاده از الگوی عبارات با قاعده فرمت فایل درخواستی را بررسی کرده، اگر فرمت مورد نظر جزء مواردی باشد که نمی خواهیم به صورت مستقیم دریافت شوند، آن را به صورت پارامتر به یک فایل PHP ارسال می کنیم (این کار در سرور و بدون اطلاع کاربر انجام می شود)، به نمونه زیر توجه کنید.
RewriteEngine on
RewriteRule ^file/([^/]+)(\.zip|\.pdf|\.jpg)$ /limit-direct-access/file/download.php?file=$1$2 [NC,L]
در این مثال ساده، در ریشه یا همان root سایت دایرکتوری با نام فرضی limit-direct-access ساخته ایم که درون آن یک فایل htaccess. با دستورات بالا قرار دارد، همچنین یک فولدر با نام file که درون آن فایل download.php به همراه سایر فایل های آماده برای دانلود جای گرفته اند (با دقت به قسمت دوم دستور RewriteRule، درک ترتیب قرار گرفتن فولدرها ساده می شود)، لذا در حالت عادی کاربر برای دانلود فایل فرضی test.zip از دایرکتوری file باید نمونه لینک زیر را از سرور درخواست کند:
http://localhost/limit-direct-access/file/test.zip
اما با توجه به دستور RewriteRule نوشته شده، کاربر بدون اینکه متوجه شود، لینک زیر را از سرور درخواست خواهد کرد:
http://localhost/limit-direct-access/file/download.php?file=test.zip
در واقع لینک اصلی برای سرور مفهوم لینک Rewrite شده را دارد.

بررسی مجوزها و ارسال فایل برای دانلود با PHP


قسمت اول کار که تغییر مسیر لینک کاربر از حالت مستقیم به غیر مستقیم بود به درستی انجام شد! حال نوبت PHP است که کار بررسی مجوزهای ورود، پرداخت و... را انجام دهد و در صورتی که شرایط باب طبع ما باشد، فایل را به مرورگر جهت دانلود ارسال کند، به نمونه زیر توجه کنید.
<?php
@$file_name = $_GET['file'];
//echo $file_name;

//بررسی مجوزهای کاربر
//تعیین نحوه بررسی مجوزها با توجه به برنامه و هدف شما می تواند متفاوت باشد، به طور مثال ممکن است هنگامی که کاربر مبلغ لینک را پرداخت کرده و تراکنش موفقیت آمیز باشد، ضمن نگهداری اطلاعات در دیتابیس جهت استفاده های بعدی، یک سشن آی دی تنظیم کنید، اکنون در هنگام دانلود می توان آن سشن آی دی را بررسی کرد و اگر تنظیم شده باشد، اجازه دسترسی به کاربر داد، یا برای کاربران وارد شده به سایت از همین شیوه می توان استفاده نمود.
$user_access = TRUE;

//کاربر مجاز به دانلود است
if($user_access == TRUE){
    //تابع برای بدست آوردن پسوند فایل
    function getExtension($file){
        preg_match('/\.[^\.]+$/i', $file, $ext);
        return $ext[0];
    }
    
    //نوع فایل    
    $file_type = NULL;
    switch(getExtension($file_name)){
        case 'zip':
        $file_type = 'application/zip';
        break;
        case 'pdf':
        $file_type = 'application/pdf';
        break;
        case 'jpg':
        $file_type = 'image/jpeg';
        break;                
    }
    
    //ارسال فایل به مرورگر برای دانلود
    ob_start();
    header('Content-Description: File Transfer');
    //header('Content-Type: application/octet-stream');    
    header('Content-Type: '.$file_type);
    header('Content-Disposition: attachment; filename='.$file_name);
    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_name"));
    ob_clean();
    flush();
    readfile("$file_name");
    exit;
}
?>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>وبگو | محدود کردن دسترسی مستقیم به لینک دانلود</title>
<!-- https://webgoo.ir -->
</head>
<body>
<?php
//کاربر مجاز به دانلود نیست
if($user_access == FALSE){
    echo 'Error!';    
}
?>
</body>
</html>
توضیح:
- همان طور که گفتیم نام فایل به صورت یک پارامتر و از طریق متد GET به فایل PHP ارسال می شود، بنابراین در خط اول متغیر file_name را با این روش مقداردهی می کنیم (که برابر با مقادیر دریافتی از پارامتر file است).
- در گام بعدی نیاز به بررسی مجوز دانلود کاربر است، نحوه انجام این مرحله کاملا دلخواه بوده و بستگی به هدف شما دارد، آنچه برای ما اهمیت دارد، مقداردهی متغیر user_access به صورت TRUE یا FALSE است، به طور مثال می توانید برای کاربرانی که تراکنش آنها موفقیت آمیز باشد، یک سشن آی دی تنظیم کنید یا فیلدی را در دیتابیس به صورت حالت پرداخت تعریف کرده و با تطبیق اطلاعات (نام کاربری و کلمه عبور)، وضعیت مجوز دانلود کاربر را بررسی کنید، در هر صورت از هر روشی که استفاده کنید نهایتا باید به نتیجه TRUE یا FALSE ختم شود، لطفا به جهت مفصل بودن این مبحث، در این رابطه به آموزش های سشن و نحوه ایجاد سیستم ورود و خروج سایت مراجعه کنید.
- پس از تعیین حالت TRUE یا FALSE برای متغیر user_access، در صورتی که مقدار TRUE باشد، یعنی کاربر مجاز به دانلود بوده و لذا باید فایل را به مرورگر ارسال کنیم، بدین منظور هم می توانید از دستور زیر برای تعیین نوع MIME فایل استفاده کنید.
header('Content-Type: application/octet-stream');
این دستور به صورت کلی است و برای اکثر فایل ها کاربرد دارد، هم می توانید به صورت اختصاصی نوع MIME فایل ها را با تابع getExtension و دستور switch مشخص کنید (این کار در نمونه کد آموزش حاضر انجام شده است).
نکته: MIME یک استاندارد تعریف شده در وب برای تعیین فایل های مختلف از نظر نوع است که می توانید لیستی از آنها را در لینک زیر مشاهده کنید.
لیست فرمت ها و معادل آنها در استاندارد MIME
- دستورات header که در ادامه تنظیم شده اند برای ارسال صحیح فایل به مرورگر و رعایت استانداردهای HTTP لازم هستند.
- تابع ob_clean و flush برای مدیریت بهتر نقل و انتقال اطلاعات و پاک کردن موارد اضافی از سرور است (ضروری نیست).
- در نهایت نیز تابع readfile فایل مورد نظر را به مرورگر ارسال کرده و دستور exit باعث پایان اجرای کدها می شود.
نکته 1: در صورتی که مقدار متغیر user_access برابر FALSE باشد، بخش دوم دستورات اجرا شده و پیغام Error نمایش داده می شود.
نکته 2: دقت کنید که به دلیل استفاده شدن از توابع header در کد، نباید قبل از اجرای این توابع هیچ نوع خروجی به مرورگر ارسال شود، این خروجی می تواند شامل BOM یا Byte Order Mark نیز شود، لذا باید مطمئن شوید که فایل PHP شما بدون BOM است که بدین منظور می توانید از برنامه Adobe Dreamweaver یا ++Notepad استفاده کرده و BOM را با ذخیره مجدد فایل حذف کنید (در نرم افزار ++Notepad باید از منوی Encoding و امکان Convert to UTF-8 without BOM استفاده کنید).

دانلود نمونه فایل های آموزش


دانلود نمونه فایل های آموزش محدود کردن  لینک دانلود مستقیم فایل ها با PHP و htaccess
دسته بندی: آموزش کاربردی » PHP
related مطالب بیشتر:
نمایش قسمتی از متن و پاراگراف با PHP
ارسال ایمیل با PHP و کلاس PHPMailer
دریافت و نمایش پیج رنک گوگل با PHP
تبدیل تاریخ میلادی، شمسی با مبدل JDF در PHP
نمایش آمار بازدیدها با PHP بدون استفاده از دیتابیس
دیدگاه
more ۱۳۵ دیدگاه برای این مطلب ارسال شده است.
more چینش دیدگاه ها به ترتیب از جدیدترین به قدیمی ترین است.
کوروش عباسی
۱۸:۵۶ ۱۴۰۰/۰۷/۱۰
دومی که فرمودید (یا هنگام دانلود فایل می خواهید ابتدا دسترسی کاربر در دایرکتوری دیگری بررسی و سپس فایل از receiver.php به مرورگر ارسال شود؟ لطفا دقیقا مراحل کار را مشخص کنید تا امکان راهنمایی درست وجود داشته باشد هر کدام از حالت های بالا سناریوی متفاوتی طلب می کنند.)
در اصل :
میخوام زمانی که کاربر خواست یک فایل رو دانلود کنه بجای اینکه درخواست دانلود به receiver.php ارسال بشه از طریق دستور get درخواست رو به سمت سایت وردپرسم ارسال کنه ، یعنی سایت بارگزاری بشه به شکل زیر درخواست بده :
https://example.com/?Request=download&file=file.mp4&folder=01/23
برای انجام این کار در درجه اول باید در دایرکتوری ریشه سایت فایل htaccess داشته باشیم به فرض اگر مسیر درخواستی کاربر به صورت زیر باشد:
https://example.com/?Request=download&file=file.mp4&folder=01/23
باید در ریشه سایت فایل htaccess داشته باشیم یا به فایل htaccess موجود دستورات جدید اضافه کنیم.
به نظر گام دوم هدایت درخواست کاربر به یک فایل PHP برای بررسی و اعتبارسنجی دسترسی قبل از دانلود است که برای این کار می توانیم از URL Rewrite استفاده کنیم، به فرض (کد تست نشده):
RewriteEngine On
RewriteCond %{THE_REQUEST} ^GET\ /\?Request=([^\s&]+)&file=([^\s&]+)&folder=([^\s&]+) [NC]
RewriteRule (.*) /plugin/download.php?request=%1&file=%2&folder=%3 [NC,L]
در نهایت در download.php می توانیم با متد GET پارامترها را دریافت و از همین فایل یا با include کردن receiver.php در download.php فایل درخواستی کاربر را به روش دلخواه از جمله استفاده از X-Sendfile به مرورگر کاربر ارسال کنیم یا اگر مجوز دانلود وجود نداشت پیغام خطا نمایش دهیم.
کوروش عباسی
۰۷:۵۵ ۱۴۰۰/۰۷/۱۰
سلام خسته نباشید میگم به وبگو عزیز من با این آموزش تونستم output buffering رو پیاده کنم یه سوال داشتم واقعا داره منو اذیت میکنه این موضوع از طریق وردپرس دارم این کار رو انجام میدم و از طریق فایل receiver.php که داخل پوشه کتابخونه وردپرس هست یعنی :
RewriteRule ^files/(.*)(\.zip|\.pdf|\.jpg|\.mp4|\.avi)$ https://example.com/wp-content/uploads/custom-files/files/receiver.php?file=$1$2 [NC,L]
چطور میتونم این فایل رو به پوشه افزونه انتقال بدم و از طریق htaccess بگم برو تو پوشه افزونه یا قالبم اونجا بهت میگم دسترسی از چه قراره - چون من قالب وردپرس یا افزونه وردپرس میخوام بنویسم نمیخوام این فایلا توی کتابخونه وردپرس ایجاد بشه تا هر کسی جداگانه بتونه ببره و برای قالبای دیگه استفاده کنه یه نفر گفته بود که از طریق
header("X-Sendfile")
باید انجام بشه نمیدونم واقعا سردرگمم
افزونه ای مثل ووکامرس هم از طریق nginx همین روش رو پیاده کرده که من واقعا ازش سر در نمیارم فقط میخوام در حدی باشه که دسترسی تعیین کنم یا ریدایرکت انجام بدم که این کارو انجام دادم فقط نمیخوام تو پوشه کتابخونه وردپرس باشه
اگر درست متوجه سوال شده باشیم می خواهید در هنگام آپلود فایل توسط کاربر دسترسی را بدون مراجعه به فایل receiver.php بررسی کنید؟ یعنی فایل اول آپلود شود اما قبل از ذخیره سازی دسترسی کاربر اعتبارسنجی شود؟ یا هنگام دانلود فایل می خواهید ابتدا دسترسی کاربر در دایرکتوری دیگری بررسی و سپس فایل از receiver.php به مرورگر ارسال شود؟ لطفا دقیقا مراحل کار را مشخص کنید تا امکان راهنمایی درست وجود داشته باشد هر کدام از حالت های بالا سناریوی متفاوتی طلب می کنند.
جین مین
۱۳:۴۸ ۱۴۰۰/۰۴/۰۶
با سلام و وقت بخیر
من تمام مراحل رو به نظر خودم درست انجام دادم و فایل هم دانلود میشه اما مشکل اصلی اونجاست که فیلم با حجم بایت دانلود میشه در صورتی که حجم رو هم بررسی کردم، مقدار رو دریافت و به header ارسال میکرد ولی نمیدونم مشکل کجاست...
ممنون میشم راهنمایی کنید.
فایل پیوست:
https://uupload.ir/view/att_i08i.txt
مشکل مطرح شده با نمونه کد زیر توسط ارسال کننده یادداشت بالا پیش از بررسی ما بر طرف شد، با سپاس فراوان از ایشان به خاطر اطلاع رسانی و به اشتراک گذاری:
<?php
$file = $_GET['file'];
$fp = @fopen($file, 'rb');
$size = filesize($file);
$length = $size;
$start = 0;
$end = $size - 1;
header('Content-type: video/mp4');
header("Accept-Ranges: bytes");
if (isset($_SERVER['HTTP_RANGE'])) {
$c_start = $start;
$c_end = $end;
list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
if (strpos($range, ',') !== false) {
header('HTTP/1.1 416 Requested Range Not Satisfiable');
header("Content-Range: bytes $start-$end/$size");
exit;
}
if ($range == '-') {
$c_start = $size - substr($range, 1);
} else {
$range = explode('-', $range);
$c_start = $range[0];
$c_end = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $size;
}
$c_end = ($c_end > $end) ? $end : $c_end;
if ($c_start > $c_end || $c_start > $size - 1 || $c_end >= $size) {
header('HTTP/1.1 416 Requested Range Not Satisfiable');
header("Content-Range: bytes $start-$end/$size");
exit;
}
$start = $c_start;
$end = $c_end;
$length = $end - $start + 1;
fseek($fp, $start);
header('HTTP/1.1 206 Partial Content');
}
header("Content-Range: bytes $start-$end/$size");
header("Content-Length: " . $length);
$buffer = 1024 * 8;
while (!feof($fp) && ($p = ftell($fp)) <= $end) {
if ($p + $buffer > $end) {
$buffer = $end - $p + 1;
}
set_time_limit(0);
echo fread($fp, $buffer);
flush();
}
fclose($fp);
exit();
حسینی
۲۰:۲۰ ۱۴۰۰/۰۲/۲۴
خیلی ممنونم. عالی بود.
readfile از کدها جا افتاده بود. الان کد کار میکنه.
سپاس
حسینی
۱۹:۴۴ ۱۴۰۰/۰۲/۲۴
ممنونم. خیلی سخت گفتین من هیچی متوجه نشدم. توی htaccess مواردی که گفتین رو درست کردم. الان اینو پیدا کردم.
$filename = basename($file);
$file_extension = strtolower(substr(strrchr($filename,"."),1));

switch( $file_extension ) {
case "gif": $ctype="image/gif"; break;
case "png": $ctype="image/png"; break;
case "jpeg":
case "jpg": $ctype="image/jpeg"; break;
case "svg": $ctype="image/svg+xml"; break;
default:
}
header('Content-type: ' . $ctype);
من توی کد بالا به جای file آدرس واقعی فایل رو نمایش دادم . اما هیجی نمایش داده نمیشه. احیانا خطی چیزی ازش کم نیست؟
منبع :
https://stackoverflow.com/questions/2633908/php-display-image-with-header/2634072
کدی که درج کرده اید ناقص است، برای ارسال فایل به مرورگر از کد درج شده در آموزش (تست شده) یا کدی استفاده کنید که قسمت header آن کامل باشد، در تئوری کار ساده است، زمانی که می خواهیم یک فایل تصویر را نمایش دهیم باید آن فایل را از سرور در تگ src (یا به صورت مستقیم) درخواست کنیم به فرض:
<img src="http://localhost/limit-direct-access/file/image.jpg">
در حالت عادی اگر آدرس فایل بررسی نشود قاعدتا سرور آن را در پاسخ مرورگر ارسال کرده و مرورگر تصویر را نمایش می دهد، حال برای داشتن کنترل روی این فرآیند با دستور htaccess زیر:
RewriteEngine on
RewriteRule ^file/([^/]+)(\.zip|\.pdf|\.jpg)$ /limit-direct-access/file/download.php?file=$1$2 [NC,L]
پاسخ سرور را به بررسی فایل download.php موکول می کنیم، این فایل جایی است که باید وضعیت مجوزها را بررسی کنیم که خود مبحث جدا دارد و باید با سشن ها و کار با دیتابیس آشنا باشیم، به فرض اینکه کاربر مجاز باشد سربرگ های header با توجه به پسوند فایل (jpg) تنظیم و نهایتا فایل با readfile از سرور به سمت مرورگر ارسال و نمایش داده می شود، برای تست کدهای آموزش می توانید مراحل زیر را انجام دهید:
- نمونه فایل های آموزش را از لینک درج شده در انتهای مطلب دانلود کنید.
- فایل ها را به فولدر www برنامه سرور مجاز (به فرض WampServer) انتقال دهید.
- در فولدر limit-direct-access یک فایل با نام index.php بسازید و کد زیر را در آن درج کنید:
<img src="http://localhost/limit-direct-access/file/image.jpg">
- در فولدر file تصویری با نام image.jpg داشته باشید.
- فایل index.php را از طریق مرورگر فراخوانی کنید، به فرض:
http://localhost/limit-direct-access/
اگر همه چیز درست باشد باید تصویر را در مرورگر مشاهده کنید.
- مقدار متغیر user_access را در خط 7 فایل download.php با مقدار false جایگزین کنید.
- فایل index.php را رفرش کنید، اکنون فایل تصویر نباید نمایش داده شود!
حسینی
۱۹:۱۳ ۱۴۰۰/۰۲/۲۴
سلام و عرض ادب
یه سوال داشتم. من دارم یه سامانه می نویسم که در اون افراد عکس کارت ملی رو میفرستن با فرمت jpg و png. حالا موقعی که آدرس عکس مستقیما وارد میشه ، عکس قابل مشاهده هست و حتی موقعی که کاربر لاگین نکرده هم آدرس کار می کنه.
خواستم ببینم راهی هست که بشه فقط زمانی که کاربر لاگین کرده لینک عکس کار کنه و موقعی که لاگین نکرده پیام شما مجوز دسترسی ندارین رو بهش نشون بدیم؟
این آموزش دقیقا در همین خصوص است منتها باید کدها را با سیستم ورود و خروج کاربر ترکیب کنید، در این آموزش فرض بر این است که کاربر مجاز است و متغیر user_access را true در نظر گرفته ایم، می توانید لینک قسمت src تصویر را به دایرکتوری file ارجاع دهید به فرض:
<img src="http://localhost/limit-direct-access/file/image.jpg">
با توجه به دستورات htaccess فایل زیر از سرور درخواست می شود:
/file/download.php?file=image.jpg
در فایل download.php می توانید وضعیت ورود و مجوزهای کابر را بررسی کنید و اگر همه چیز مرتب بود فایل را ارسال کنید، مهم این است چگونه قسمت های مختلف را به هم مرتبط کنید.
mahdi
۱۳:۲۱ ۱۴۰۰/۰۲/۱۷
سلام استاد عزیز وقتتون بخیر،
استاد عزیز یه آپلودر نوشتم و فقط نمیدونم باهاش چکار کنم
1- یه کلاس جامع برای کار با فایل ها بسازم و آپلودر هم بعنوان یکی از متدهاش قرار بدم؟ که اینو فکر میکنم بیخودی حجم رو اضافه میکنم و خود توابع کار با فایل ها خیلی بهترو تمزتر هستن
2- یه کلاس بسازم که یکی از متدهاش همین آپلودر باشه و کم کم متدهای دیگه هم که نسبتا پیچیدگی دارن رو بهش اضافه کنم ، مثل مثلا برای دانلود یا لینک یک بار مصرف و ... که اینا هم فکر میکنم با توجه به موقعیت نوشته بشه بهتره
3- بزارمش کنار متدهایی که برای کار با دیتابیس نوشتم و هرجا خواستم فراخوانیش کنم؟
من خودم فکرم سومیه ولی نظر شما برام مهمتره
خیلی ممنون استاد عزیز موفق باشی
به نظر کدهایی که به صورت مجموعه هستند و در نهایت یک کار خاص انجام می دهند (به طور مثال آپلود فایل) را به شکل کلاس جداگانه تعریف و برای کلاس متناسب با نیازتان متد داشته باشید، در پروژه ها هر کجا نیاز بود کلاس را به سایر کلاس های برنامه اضافه و با include و فراخوانی به متدهای آن دسترسی پیدا کنید، متدها می توانند Static باشند و با کاراکتر :: قابل دسترسی (این حالت با مورد اول فرق دارد، در اینجا کلاس جامع نیست صرفا آپلود فایل انجام می شود نه موارد دیگر).
به این شیوه با یک بار نوشتن کلاس ها در برنامه های مختلف می توانید از آن استفاده کنید و نیازی به دوباره نویسی نیست.
مورد سوم هم در صورت نیاز به ذخیره سازی اطلاعات فایل در دیتابیس گزینه مناسبی است.
korosh abbasy
۲۳:۱۵ ۱۳۹۹/۱۲/۲۹
سلام وقت بخیر ببخشید در مورد این مطلب سوالی پرسیدم شما در مورد output buffering توضیح دادید کد کار نمیکنه میخواستم ببینم نیازی هست من توی فایل htaccess تغییری ایجاد کنم توی گیت هاب یک نفر در مورد این توضیحی داده من متوجه نشدم
Your .htaccess solution is a good idea, to get it to work, your .htaccess needs to be in a sub-directory with the source videos, and nothing else. Update it so that it looks like this:

RewriteEngine on
RewriteCond %{HTTP_REFERER} !^http://example.com/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://www.example.com/.*$ [NC]
RewriteRule .(mp4|mp3|avi)$ - [F]`
Alternatively this should work too (to completley block access to your video conent)

RewriteEngine On
RewriteCond %{REQUEST_URI} \\.(mp4|mp3|avi)$ [NC]
RewriteRule ^.* - [F,L]
It is required to include both codes together:

RewriteEngine On
RewriteCond %{REQUEST_URI} \\.(mp4|mp3|avi)$ [NC]
RewriteCond %{HTTP_REFERER} !^http://sample.com/.*$ [NC]
RewriteRule ^.* - [F,L]
دستورات htaccess درج شده برای مسدود کردن امکان دانلود مستقیم فایل است که در آموزش شیوه کامل آن توضیح داده شده است، اما نمونه کد آماده برای ارسال فایل هایی که معمولا نیاز به دانلود چندقسمتی دارند مانند فایل های ویدئویی کاربرد دارد، برای تست و بررسی بیشتر و در صورت تمایل می توانید برنامه تیم ویور را نصب و با ارسال ایمیل (از بخش تماس با ما) اعلام کنید تا در تاریخ و زمان مناسب سورس کدها به صورت آنلاین در سیستمتان خطایابی شوند.
korosh abbasy
۱۳:۳۵ ۱۳۹۹/۱۲/۲۷
سلام دم شما گرم
این دستور برای خوندن فایل هم استفاده میشه؟
من میخوام دسترسی تعیین کنم که اگر یک متغییر true بود صفحه اجازه خوندن ویدئو رو بده
در کل مبنای کار تفاوتی نمی کند اما در خصوص پخش ویدئو مباحث پیچیده تری مانند بحث Buffering و دانلود چند تکه فایل (Range) با امکان ادامه دانلود (Resume) وجود دارد که به همین دلیل نحوه ارسال فایل از سمت سرور به سمت کاربر متفاوت است، به فرض کد آماده زیر برای مدیریت ارسال فایل ویدئویی با PHP کاربرد دارد (تست نشده!):
<?php
$path = 'file.mp4';
$size = filesize($path);
$fm = @fopen($path, 'rb');
if(!$fm) {
header("HTTP/1.0 404 Not Found");
die();
}

$begin = 0;
$end = $size;

if(isset($_SERVER['HTTP_RANGE'])) {
if(preg_match('/bytes=\h*(\d+)-(\d*)[\D.*]?/i', $_SERVER['HTTP_RANGE'], $matches)) {
$begin = intval($matches[0]);
if(!empty($matches[1])) {
$end = intval($matches[1]);
}
}
}

if($begin > 0 || $end < $size) {
header('HTTP/1.0 206 Partial Content');
} else {
header('HTTP/1.0 200 OK');
}

header("Content-Type: video/mp4");
header('Accept-Ranges: bytes');
header('Content-Length:' . ($end - $begin));
header("Content-Disposition: inline;");
header("Content-Range: bytes $begin-$end/$size");
header("Content-Transfer-Encoding: binary\n");
header('Connection: close');

$cur = $begin;
fseek($fm, $begin, 0);

while(!feof($fm) && $cur < $end && (connection_status() == 0)) {
print fread($fm, min(1024 * 16, $end - $cur));
$cur += 1024 * 16;
usleep(1000);
}

exit();
?>
Alireza
۱۷:۵۴ ۱۳۹۹/۰۸/۲۹
خیلی ممنون از پاسخگویی سریع!
بله خوشبختانه سرور هاست دانلود LiteSpeed هست و از جدیدترین PHP هم پشتیبانی میکنه. تو قسمت path هم دایرکتوری کلی فایل ها رو نوشتم که روی تمام فایل ها همیشه اعمال بشه. متاسفانه htaccess هم نوشته که do not edit و فکر نکنم هم عملی باشه.
سایر موارد هم بله متود get انجام میشه و لینک کاملا متفاوتی به نمایش میزاره.
خیلی خیلی ممنونم
پیروز و سربلند باشید!
Alireza
۰۲:۲۷ ۱۳۹۹/۰۸/۲۹
عرض سلام و خسته نباشید
از مطالب استفاده کردم و نظرات هم خوندم واقعا مفید بودن. یکی دو نفر مشکلی شبیه بنده داشتن. من میخوام تو هاست دانلود فایل هایی از طریق افزونه خاص تو وردپرس که رو هاست اصلیم هست به صورت ftp کار میکنه اون فایل ها رو بخونه. اپلیکیشن فایلها رو میخونه و هیچ لینکی از اون فایلها یا حتی سابدامنه هاست دانلود هم لو نمیده. یعنی از این سمت امنیتی تکمیله.
فقط میخوام کاری کنم امکان دانلود بسته بشه و حالت internal redirect باشه. برای همین از این ماژول استفاده میکنم:
<?php
//rule to exclude dl and only view
header('X-LiteSpeed-Location: path');
?>
اینو تو یه فایل ایندکس تو دایرکتوری مربوطه گذاشتم. خواستم بپرسم همین کفایت میکنه؟ کسی آدرس سابدامنه نداره و ایندکس شدن و این مسائل امنیتی هم نیست که فایل ها دسترسی داشته باشن.
ممنون میشم راهنمایی کوچیکی کنید
در صورتی که سرور هاست دانلود LiteSpeed باشد و از PHP پشتیبانی کند دستور شما کاربرد دارد، در واقع در قسمت Path دستور بالا باید آدرس URL فایل ها را تنظیم کنید که پارامترهای این آدرس (از جمله نام فایل) می توانند با متد GET از سمت سرور اصلی دریافت شوند، سرور اصلی درخواست را به این فایل ارسال و PHP فایل مورد نظر را در پاسخ جهت دانلود معرفی می کند.
متاسفانه خیلی از هاست های دانلود از PHP پشتیبانی نمی کنند و بنابراین دستورات اینچنینی کاربردی ندارند، از طرفی دستورات htaccess هم معمولا در اینگونه سرورها پشتیبانی نمی شوند، در صورت پشتیبانی نمونه دستور زیر می تواند دانلود از طریق درج آدرس مستقیم را ممنوع کند:
<FilesMatch ".*">
Order Allow,Deny
Deny from All
</FilesMatch>
البته این دستور ممکن است بسته به تنظیمات قسمت AllowOverride عمل نکند!
در هر صورت به نظر ساده ترین راه این است که نام دایرکتوری های دانلود را به عبارات طولانی و نامفهوم تبدیل کنید تا امکان دانلود اتفاقی نزدیک به صفر باشد.
محسن
۲۳:۳۱ ۱۳۹۹/۰۶/۱۶
سلام و عرض ادب مجدد
کد زیر هم کار نمیکنه
RewriteCond %{HTTP_HOST} ^([a-z0-9]+)\.myblog\.ir
RewriteRule ^upload/(.*)/([^/]+)$ upload/%1/$1/$2 [L,QSA]
مشکل چی میتونه باشه ؟!
Syntax دستور مشکلی ندارد باید دید قصد ریدایرکت چه آدرس هایی را دارید؟ در صورت امکان یک نمونه آدرس آنلاین جهت تست و بررسی قرار دهید، ممکن است دستورات با موارد دیگری در htaccess اختلال داشته باشند، رفع مشکلات اینچنینی ممکن است نیازمند دسترسی و ویرایش فایل htaccess و آزمایش و خطا باشد.
محسن
۰۲:۰۱ ۱۳۹۹/۰۶/۱۶
سلام و عرض ادب
لطفا راهنمایی کنید مشکل کد زیر چیه
RewriteCond %{HTTP_HOST} ^([a-z0-9]+)\.myblog\.ir
RewriteRule ^upload/(.*)/(.*)$ upload/%1/$1/$2 [L,QSA]
احتمالا دور تکرار بینهایت اتفاق می افتد، دستور زیر را امتحان کنید:
RewriteCond %{HTTP_HOST} ^([a-z0-9]+)\.myblog\.ir
RewriteRule ^upload/(.*)/([^/]+)$ upload/%1/$1/$2 [L,QSA]
مهدی
۰۳:۱۳ ۱۳۹۹/۰۵/۰۸
سلام و خسته نباشید
یه مشکلی دارم که فکر کنم فقط وبگو میتونه کمک کنه سرور دانلود دارم و از اسکریپت دانلود vip استفاده میکنم وقتی لینک رو سیستم vip میگیره همه چی اوکی هست اما لینک مستقیم دایرکتوری سرور رو میدیم دانلود میشه راهی هست که لینک مستقیم سرور رو که دایرکت ادمین هم هست بست این روش رو تست کردم نشد میخوام تو public-html هر پوشه و زیر مجموعه ای هست دانلود نشه
برای استفاده از این روش دو امکان باید در سرور اصلی که فایل در آن قرار دارد فعال باشد:
- امکان اجرای دستورات فایل htaccess
- امکان اجرای دستورات برنامه نویسی PHP
با توجه به اینکه اشاره کردید از سرور دانلود استفاده می کنید احتمالا هیچکدام از موارد بالا بر روی این نوع سرویس ها فعال نیست و لذا امکان مانور وجود ندارد.
در تئوری می توان اسکریپتی نوشت که واسط بین سرور دانلود و مرورگر کاربر باشد (دریافت هم زمان فایل از سرور دانلود و ارسال آن به سمت کاربر)، کد زیر را مخصوصا با فایل های حجیم تست کنید:
$url = 'http://example.com/path/to/file.zip';
$fp = fopen($url, 'rb');
foreach(get_headers($url) as $header){
header($header);
}
fpassthru($fp);
exit;

https://www.php.net/manual/en/function.fpassthru.php
نکته: در این روش امکان "ادامه دانلود" وجود ندارد، برای ایجاد حالت ادامه دانلود باید با روش Chunked Download (دانلود چندبخشی) فایل ها در PHP آشنا باشید و کد بالا را بر این مبنا توسعه دهید، مثال (تست نشده):
https://gist.github.com/saleemkce/8603215
Farzad
۱۸:۵۶ ۱۳۹۹/۰۳/۳۰
الان وقتی فایل رو میخواد دانلود بکنه از خودش فایل میسازه ، به این صورت
file/folder1/test.zip
فایلی که میسازه و دانلود میشه:
folder1_test.zip
یعنی بعد از پوشه file هر پوشه ای باشه اونو میزاره اسم فایل و بعدش underline میزاره
با توجه به مواردی که در دستور htaccess تنظیم کرده ایم پارامتر فایل دریافتی از متد GET هم شامل دایرکتوری و هم نام اصلی فایل است، علامت / نیز در نام فایل مجاز نیست و ظاهرا مفسر PHP به صورت خودکار آن را به _ تبدیل می کند، در هر صورت خط زیر را به شکل نمونه ویرایش کنید مشکل رفع می شود:
    header('Content-Disposition: attachment; filename='.basename($file_name));
more لطفا پیش از ارسال دیدگاه نکات زیر را مد نظر داشته باشید:
- به سوالات کلی، زمانبر، مبهم و مشکلاتی که تلاشی برای رفع آنها نکرده باشید پاسخ مختصر داده شده یا به بخش برنامه نویسی اختصاصی ارجاع داده می شوند.
- کدها و اسکریپت های طولانی را ترجیحا در یک صفحه وب آنلاین یا به صورت حساب موقت و آزمایشی قرار دهید تا امکان بررسی دقیق مشکل و خطایابی میسر باشد.
- تمام دیدگاه های ارسالی خوانده شده و برای هر کاربر مدت زمان لازم جهت پاسخگویی در نظر گرفته می شود، لطفا از طرح سوالات متعدد در بازه زمانی کوتاه خودداری کنید.



 refresh
10 × 10
1 × 8
20 × 20
=