i
در حال برنامه نویسی و آماده سازی نسخه جدید «وبگو» هستیم، در این نسخه قابلیت ها و ظاهر سایت به کلی متفاوت و کاملتر خواهد بود، این فرآیند زمانبر و از مدتی پیش شروع شده و همچنان ادامه دارد، روند پیشرفت پروژه در این قسمت به صورت درصدی مشخص است و به تناوب به روزرسانی می شود.
parsgreen.com
نکته:
با توجه به تاریخ نگارش آموزش های سایت و پیشرفت تکنولوژی های مرتبط با وب در سالیان اخیر، محتوای برخی از مطالب قدیمی ممکن است نیاز به ویرایش و به روزرسانی داشته باشند که این کار هم زمان با تهیه نسخه جدید «وبگو» به مرور در حال انجام است، لطفا در استفاده از مطالب سایت به این نکته دقت داشته و حتی المقدور از چند منبع مختلف استفاده نمائید.
article

محدود کردن لینک دانلود مستقیم فایل ها با 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
sectionدسته بندی: آموزش کاربردی » PHP
related مطالب بیشتر:
» محاسبه و نمایش پیج رنک گوگل با php
» ساخت منوی هوشمند با php و css!
» تبدیل تاریخ میلادی به شمسی، با استفاده از مبدل jdf در php
» ساخت فید خوان آر اس اس (RSS Feed Reader) با php
» ارسال ایمیل با php و کلاس phpmailer
commentنظرات (۹۱ یادداشت برای این مطلب ارسال شده است)
نویسنده: امير
زمان: ۱۵:۱۸:۱۳ - تاریخ: ۱۳۹۳/۰۵/۰۴
سلام
آيا كاربر ميتونه با روشي لينك مستقيم فايل رو بدست بياره ؟
با تشكر
پاسخ: 
سلام
لینک ها در ظاهر مستقیم هستند، منتها در سرور به جای ارسال فایل، ابتدا یک صفحه فراخوانی و در صورت صلاحدید فایل ارسال می شود، لذا کاربر عملا متوجه چیزی نمی شود!
در صورت استفاده صحیح و عدم وجود مشکل در بخش های دیگر، راه دور زدنی وجود ندارد!
نویسنده: ایمان
زمان: ۱۸:۴۹:۵۰ - تاریخ: ۱۳۹۳/۰۵/۱۷
سلام و خسته نباشید
چیز جالبیه ولی یه مشکل داره مثلا اگر کاربر ادرس :
http://localhost/limit-direct-access/file/
رو بزنه به راحتی به همه ی فایلهای دسترسی پیدا میکنه!
اینو چطور میشه حل کرد؟
پاسخ: 
سلام
این موضوع به تنظیمات Indexing سرور شما بستگی دارد و مربوط به کد نیست! در هر حال با قرار داد دستور زیر در فایل htaccess در ریشه سایت یا قرار دادن یک فایل index.html در همان دایرکتوری مشکل قابل رفع است:
Options -Indexes
نویسنده: amir
زمان: ۱۴:۲۴:۳۰ - تاریخ: ۱۳۹۳/۰۷/۰۷
من از این کد برای محدود کردن استفاده کردم که اگه لینک دانلود به جز سایت من سایتهای دیگه باشه ریدایرکت بشه به سایت پیج اصلی من اما وقتی کاربر میاد تو سایت و میره تو پیج مطلب همون سایت و لینک دانلود رو کلیک میکنه دانلود استارت نمیخوره دوباره ریدایرکت میشه به پیج اصلی علت چی میتونه باشه ؟
کدی که استفاده کردم در هاست دانلود به این صورت هستش
RewriteEngine on
#RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)?vatanpdf.com/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://(www\.)?pdf-book.net/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://(www\.)?dl.pdf-book.net/.*$ [NC]
RewriteRule \.(zip|ZIP|pdf|PDF)$ "http\:\/\/vatanpdf\.com\/" [R=301,L]
پاسخ: 
چند لینک از سایت شما تست شد، ظاهرا مشکل بر طرف گردیده؟! در غیر اینصورت یک نمونه لینک قرار دهید تا بررسی شود.
نویسنده: aref
زمان: ۱۸:۰۹:۲۳ - تاریخ: ۱۳۹۳/۰۷/۱۱
سلام یک سوال :
مثلا در دایرکتور دانلود ما یک فایل zip هست :
local/tst/dl/aref.zip
اگر کاربر اسم فایل رو بدونه دیگه از download.php نمیزنه و از فیلتر download.php میتونه دور بزنه.
چطوری همه فایل ها که در
local/tst/dl
وجود دارن کاری بکنیم که از download.php رد بشن و مستقیم باز نشن ؟
پاسخ: 
سلام
لطفا آموزش را دقیق تر مطالعه کنید! در روش گفته شده امکان دور زدن وجود ندارد چون با دستورات htaccess جلوی این کار گرفته می شود، باید با توجه به دایرکتروی مورد نظرتان، لینک دانلود اصلی را به فایل download.php ارجاع دهید.
نویسنده: ali
زمان: ۱۷:۳۳:۲۱ - تاریخ: ۱۳۹۳/۰۷/۱۸
ممنون بابت آموزش خوبتون .
راهی هست که فایل ها قابلیت resume داشته باشن ؟
پاسخ: 
این قابلیت به امکانات و تنظیمات سرور برمی گردد، فرقی ندارد از چه کدی استفاده کنید.
نویسنده: پرویز
زمان: ۱۸:۲۹:۰۴ - تاریخ: ۱۳۹۳/۰۸/۱۹
سلام خدمت شما ، عبارت
return $ext[0];
به چه منظوری است؟ لطفا توضیح دهید.
پاسخ: 
سلام
این قسمت نتیجه تابع preg_match را (این نتیجه به صورت آرایه در متغیر ext وجود دارد) به عنوان خروجی تابع getExtension برمیگرداند (که در نهایت همان فرمت فایل است).
http://php.net/manual/en/function.preg-match.php
نویسنده: ahangbaz
زمان: ۰۲:۴۵:۱۶ - تاریخ: ۱۳۹۳/۰۸/۲۱
خیی عالی بود خیلی
نویسنده: فرهاد
زمان: ۱۷:۲۹:۵۴ - تاریخ: ۱۳۹۳/۰۹/۰۲
سلام
تو لوکال هاست به صورت مستقیم دانلود میشه!
لطفا روشی ارائه بدید که تو لوکال هاستم جواب بده.
لطفا در صورت امکان برام ایمیل کنید.
پاسخ: 
سلام
به نظر امکان Rewrite در برنامه لوکال شما فعال نیست! برای فعال شدن Rewrite باید mod_rewrite و mod_headers در برنامه سرور مجازی شما فعال باشند.
نویسنده: leila
زمان: ۱۰:۱۳:۵۳ - تاریخ: ۱۳۹۳/۰۹/۰۶
سلام.
من دارم يك نمونه سايت طراحي ميكنم . يه فايل htaccess دارم. ولي هيچ كدوم از فايلهاي css ,jquery رو اجرا نميكنه.
تو htaccess اينا هست:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME}% !-d
RewriteCond %{REQUEST_FILENAME}% !-f
RewriteCond %{REQUEST_FILENAME}% !-l
RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]
هم تو netbeans و هم تو dreamvewear امتحان كردم.
همه ي صفحاتو باز ميكنه اما فايلهاي css ,jquey رو اجرا نميكنه
پاسخ: 
سلام
به نظر نمی رسد مشکل ارتباطی به دستورات فایل htaccess داشته باشد، ممکن است از آدرس دهی اشتباه و... باشد.
نکته: تست صفحات را در مرورگر انجام دهید نه در برنامه ها.
نویسنده: ali
زمان: ۱۲:۳۴:۰۵ - تاریخ: ۱۳۹۳/۰۹/۱۳
کدهای htaccess. برای من جواب نمیده. این میتونه محدودیتی از طرف هاست من ایجاد شده باشه ؟
روی هاست دیگه جواب داد.
پاسخ: 
بله، اگر هیچ دستوری در سرور شما اجرا نمی شود، می تواند از تنظیمات سرور یا اعمال محدودیت روی آن باشد (به طور مثال در سرورهای دانلود معمولا بیشتر امکانات محدود می شود).
نویسنده: فرهاد
زمان: ۲۰:۴۸:۳۶ - تاریخ: ۱۳۹۳/۰۹/۱۷
میشه کلا یک روش دیگه برای محدود کردن لینک دانلود ارائه بدید ؟
این روشو میشه دور زد !
مثل این سایت های دانلود که هر جور آدرس دانلود رو بزنی میره صفحه دانلود.
با تشکر از سایت مفیدتون
پاسخ: 
این روش در صورت تنظیم درست و کمی آشنایی با htaccess به هیچ وجه قابل دور زدن نیست! مگر در مواردی مانند هک و... که بحث دیگری است و در هیچ شرایطی امنیت صد در صد وجود ندارد، مشخص نیست دلیل شما برای این ادعا چیست؟!
نویسنده: آریا
زمان: ۰۰:۵۴:۱۳ - تاریخ: ۱۳۹۳/۰۹/۲۱
با سلام.
ممنون از سایتتون. کارتون عالیه.
راهی هست که توی این کدها علاوه بر محدود کردن لینک مستقیم سرعت دانلود رو هم کنترل کرد؟
مثلا فایل بالاتر از 60 کیلوبایت در ثانیه دانلود نشه.
ممنون میشم راهنمایی کنید.
پاسخ: 
سلام
بهترین راه برای این کار تغییر تنظیمات سرور است، با این حال نمونه کد PHP موجود در آدرس زیر می تواند کمک کند:
http://www.jonasjohn.de/snippets/php/dl-speed-limit.htm
نویسنده: آریا
زمان: ۲۲:۵۰:۰۶ - تاریخ: ۱۳۹۳/۰۹/۲۲
ممنون از پاسختون.
این کد پی اچ پی فکر کنم فقط برای یه فایل انجام میده.
تنظیمات سرور، تو هاست سیپنل لایت اسپید امکان اعمالش هست؟
البته مدیر هاستینگ میگن نمیشه.
پاسخ: 
- برای چند فایل باید در حلقه آن را تعریف کنید.
- برای اعمال این تنظیمات معمولا باید سرور دانلود یا سرور اختصاصی داشته باشید نه اشتراکی.
نویسنده: hassan
زمان: ۱۹:۳۷:۱۳ - تاریخ: ۱۳۹۳/۱۰/۲۸
سلام من هر چی میزنم دانلود میگه خطای Internal Server Error رو میده!
پاسخ: 
سلام
یا خطایی در دستورات فایل htaccess شما وجود دارد، یا اینکه دستورات htaccess در سرور شما به درستی اجرا نمی شوند (به فرض ممکن است mod_rewrite فعال نباشد).
نویسنده: HASSAN
زمان: ۱۵:۱۶:۵۱ - تاریخ: ۱۳۹۳/۱۰/۲۹
mod_rewrite رو از کجا روشن کنم؟
پاسخ: 
این کار باید از طریق تنظیمات سرور انجام شود، اگر در هاست اشتراکی هستید باید توسط پشتیبان صورت گیرد، در لوکال با زدن تیک mod_rewrite از طریق منوی Apache امکانپذیر است، همچنین mod_headers نیز باید فعال باشد.
paged صفحه 2 از 7




more لطفا دقت کنید که یادداشت های زیر منتشر نشده و حذف خواهند شد:
- یادداشت های خارج از موضوع این مطلب.
- سوالات کلی، غیر ضروری و مشکلاتی که هیچ تلاشی برای رفع آن نکرده باشید.
- نظرات حاوی کدها و اسکریپت های خیلی طولانی (به طور مثال کد کامل قالب وبلاگ).

8 × 8
 refresh
آگهی
رنگین کمان عکس
Ranginkamaan.com

آرشیو عکس های باکیفیت با موضوعات متنوع...
پرشین آی تی
Persianit.net

آموزش و دانلود پروژه های برنامه نویسی سی شارپ (#C)