View Full Version : سوالاتی در مورد آپلود عکس در Yii
Tarragon
چهارشنبه 22 بهمن 1393, 18:05 عصر
سلام
با توجه به مثال خیلی خوب Yii تونستم آپلود عکس رو درست کنم اما به چهار تا مشکل برخوردم.
۱- امنیت این کد خوبه؟ اگر نیست چطوری اون رو بالا ببریم؟
۲- چطوری می شه محدودیت سایز گذاشت یعنی اگر اندازه یا حجم عکس زیاد بود به کاربر ارور نشون بدیم تا دوباره فیلد هارو پر کنه؟
۳- آیا ذخیره کردن با نام خود عکس کار خوبیه؟ برا امنیت مشکل نداره/
۴- و چطوری می شه عکس هارو به نسبت ۱ به ۱ کراپ کرد و سایز اون رو تغییر داد و در نهایت براش thumbnail ساخت؟
پیشاپیش از شما دوستان برای کمک های مفیدتون تشکر می کنم.:قلب:
public function actionCreate()
{
$model=new Ads;
$images = array();
if(isset($_POST['Ads']))
{
$model->attributes=$_POST['Ads'];
$criteria = new CDbCriteria();
$criteria->order = "`id` DESC";
$criteria->limit = 1;
$isId = Ads::model()->findAll($criteria);
$isId = $isId[0]->id+1;
$images = CUploadedFile::getInstancesByName('images');
if (isset($images) && count($images) > 0)
{
if(!is_dir(Yii::getPathOfAlias('webroot').'/images/'. $isId))
{
mkdir(Yii::getPathOfAlias('webroot').'/images/'. $isId);
}
foreach ($images as $image => $pic)
{
if ($pic->saveAs(Yii::getPathOfAlias('webroot').'/images/'.$isId.'/'.$pic->name))
{
$model->save();
$img_add = new AdsImages();
$img_add->photo_name = $pic->name;
$img_add->ads_id = $model->id;
$img_add->save();
}
else
{
echo 'write your own';
}
}
if($model->save()){
$this->redirect(array('view','id'=>$model->id));
}
}
}
$this->render('create',array(
'model'=>$model,
));
}
MMSHFE
چهارشنبه 22 بهمن 1393, 19:03 عصر
1- امنیت نداره (میشه Shell آپلود کرد). برای افزایش امنیت باید با GD عکس رو بخونید و یک عکس جدید از روش بسازین.
2- با فیلدهای error و type شئ pic$ کار کنید.
3- خوب نیست. باگ ایجاد میکنه (بخصوص توی سرورهایی که با mod_php کار میکنن).
4- از GD باید استفاده کنید. مشابه تصاویر عادی کار کنید و برای خوندن فایل عکس اصلی که آپلود شده از pic->tempName$ استفاده کنید.
Tarragon
چهارشنبه 22 بهمن 1393, 19:41 عصر
استاد وقت دارید کد کامل رو قرار بدید؟ممنونم.
Tarragon
چهارشنبه 22 بهمن 1393, 22:08 عصر
آقای شهرکی اگر mime ها رو چک کنیم کافی نیست؟
alirezara
پنج شنبه 23 بهمن 1393, 12:50 عصر
سلام استاد شهرکی! خسته نباشید. بنده هم با این مشکل روبرو هستم. اگه یه لطفی کنید و برای آپلود امن فایل در فریم ورک yii کدی رو در تاپیک قرار بدید واقعااااااااااااا ممنون میشم.
با تشکر از خدمات خوبتون...
masato
پنج شنبه 23 بهمن 1393, 12:55 عصر
چرا از اکستنش های خود yii استفاده نمی کنید
یه سرچی بزنید حتما پیدا مینکی برای تمامی موارد بالا
alirezara
پنج شنبه 23 بهمن 1393, 12:59 عصر
من الان سرچ کردم 109 تا اکستنشن برای آپلود فایل داریم شما کدوم رو پیشنهاد میدید؟ برای من امنیت خیلی مهمه!
alirezara
پنج شنبه 23 بهمن 1393, 16:25 عصر
با سلام و خسته نباشید خدمت دوستان و اساتید گرامی .
دوستان من برای آپلود عکس کد زیر رو نوشتم اما مشکلش اینه که مقدار null را در دیتا بیس ذخیره می کنه . مثل اینکه چیزی از فرم دریافت نمیکنه. البته این کد من در حالت ویرایش هست.
از دوستان و اساتید گرامی خواهشمندم که بنده را راهنمایی کنید. با تشکر ...
کد بخش ویو :
<?php
$this->pageTitle=CHtml::encode('ویرایش تنظیمات سامانه');
$this->managersMenu=
'<div style="text-align:center">'.
CHtml::link(
CHtml::encode('مشاهده ی تنظیمات سامانه').
"
<span class='icon arrow-left'> </span>
",
array("site/infoView/1"),
array('class'=>'more-button more-button-ltr')
)
.
CHtml::link(
CHtml::encode('ویرایش تنظیمات سامانه').
"
<span class='icon arrow-left'> </span>
",
array("site/infoUpdate/1"),
array('class'=>'more-button more-button-ltr')
)
.'</div><hr />
<div class="text-align-right-dir-rtl"><b>'.CHtml::encode($model->getAttributeLabel('siteFavicon')).' : </b></div>
<br />
<div class="text-align-center-dir-rtl">
<img src="
'.Yii::app()->request->baseUrl.'
/images/logo-icon-site/'.CHtml::encode($model->siteFavicon).'
" alt="LOGO"
/>
</div>
<br />
<div class="text-align-right-dir-rtl"><b>'.CHtml::encode($model->getAttributeLabel('siteLogo')).' : </b></div>
<br />
<div class="text-align-center-dir-rtl">
<img src="
'.Yii::app()->request->baseUrl.'
/images/logo-icon-site/'.CHtml::encode($model->siteLogo).'
" alt="LOGO"
/>
</div>
<hr />
';
?>
<div id="content-page" class="span9 content group">
<div class="page type-page status-publish hentry group">
<div class="text-align-right-dir-rtl tahoma-font-12">
<?php if($message) {?>
<div class="box notice-box">
<strong>
<?php echo CHtml::encode('مدیر محترم :'); ?>
</strong>
<?php echo CHtml::encode('در صورتی که می خواهید تنظیمات سامانه را ویرایش نمائید ، از طریق فرم زیر اقدام فرمائید.'); ?>
</div>
<?php
}
else {
?>
<div class="box error-box">
<strong>
<?php echo CHtml::encode('مدیر محترم :'); ?>
</strong>
<?php echo CHtml::encode('عملیات ویرایش تنظیمات با شکست روبرو شد. لطفا دوباره تلاش کنید.'); ?>
</div>
<?php } ?>
</div>
<?php
$form=$this->beginWidget('CActiveForm', array(
'id'=>'info-form',
'htmlOptions'=>array('class'=>'contact-form ro float.right','enctype'=>'multipart/form-data','style'=>'padding-left:3%'),
'enableAjaxValidation'=>true,
'enableClientValidation'=>true
));
?>
<fieldset>
<ul>
<li class="text-field span4 text-align-right-dir-rtl tahoma-font-12">
<b><?php echo CHtml::encode($model->getAttributeLabel('siteAddress')); ?></b>
<div class="input-prepend">
<?php echo $form->textField($model,'siteAddress',array('maxlength'=>255,'class'=>'text-align-left-dir-ltr','style'=>'width:100%','tabindex'=>'2')); ?>
</div>
<div class="msg-error"><?php echo $form->error($model,'siteAddress'); ?></div>
</li>
<li class="text-field span4 text-align-right-dir-rtl tahoma-font-12">
<b><?php echo CHtml::encode($model->getAttributeLabel('siteName')); ?></b>
<div class="input-prepend">
<?php echo $form->textField($model,'siteName',array('maxlength'=>255,'class'=>'text-align-right-dir-rtl','style'=>'width:100%','tabindex'=>'1')); ?>
</div>
<div class="msg-error"><?php echo $form->error($model,'siteName'); ?></div>
</li>
</ul>
</fieldset>
<fieldset>
<ul>
<li class="text-field span4 text-align-right-dir-rtl tahoma-font-12">
<b><?php echo CHtml::encode($model->getAttributeLabel('siteFavicon')); ?></b>
<div class="input-prepend">
<?php echo $form->fileField($model,'siteFavicon',array('maxlength'=>255,'class'=>'text-align-left-dir-ltr','style'=>'width:100%','tabindex'=>'4')); ?>
</div>
<div class="msg-error"><?php echo $form->error($model,'siteFavicon'); ?></div>
</li>
<li class="text-field span4 text-align-right-dir-rtl tahoma-font-12">
<b><?php echo CHtml::encode($model->getAttributeLabel('siteLogo')); ?></b>
<div class="input-prepend">
<?php echo $form->fileField($model,'siteLogo',array('maxlength'=>255,'class'=>'text-align-left-dir-ltr','style'=>'width:100%','tabindex'=>'3')); ?>
</div>
<div class="msg-error"><?php echo $form->error($model,'siteLogo'); ?></div>
</li>
</ul>
</fieldset>
<div class="border-line"></div>
<fieldset>
<ul>
<li class="text-field span8 text-align-right-dir-rtl tahoma-font-12">
<b><?php echo CHtml::encode($model->getAttributeLabel('address')); ?></b>
<div class="input-prepend">
<?php echo $form->textField($model,'address',array('maxlength'=>255,'class'=>'text-align-right-dir-rtl','style'=>'width:100%','tabindex'=>'5')); ?>
</div>
<div class="msg-error"><?php echo $form->error($model,'address'); ?></div>
</li>
</ul>
</fieldset>
<fieldset>
<ul>
<li class="text-field span4 text-align-right-dir-rtl tahoma-font-12">
<b><?php echo CHtml::encode($model->getAttributeLabel('mobile')); ?></b>
<div class="input-prepend">
<?php echo $form->textField($model,'mobile',array('maxlength'=>255,'class'=>'text-align-left-dir-ltr','style'=>'width:100%','tabindex'=>'7')); ?>
</div>
<div class="msg-error"><?php echo $form->error($model,'mobile'); ?></div>
</li>
<li class="text-field span4 text-align-right-dir-rtl tahoma-font-12">
<b><?php echo CHtml::encode($model->getAttributeLabel('telephone')); ?></b>
<div class="input-prepend">
<?php echo $form->textField($model,'telephone',array('maxlength'=>255,'class'=>'text-align-left-dir-ltr','style'=>'width:100%','tabindex'=>'6')); ?>
</div>
<div class="msg-error"><?php echo $form->error($model,'telephone'); ?></div>
</li>
</ul>
</fieldset>
<fieldset>
<ul>
<li class="text-field span4 text-align-right-dir-rtl tahoma-font-12">
<b><?php echo CHtml::encode($model->getAttributeLabel('email')); ?></b>
<div class="input-prepend">
<?php echo $form->emailField($model,'email',array('maxlength'=>255,'class'=>'text-align-left-dir-ltr','style'=>'width:100%','tabindex'=>'9')); ?>
</div>
<div class="msg-error"><?php echo $form->error($model,'email'); ?></div>
</li>
<li class="text-field span4 text-align-right-dir-rtl tahoma-font-12">
<b><?php echo CHtml::encode($model->getAttributeLabel('fax')); ?></b>
<div class="input-prepend">
<?php echo $form->textField($model,'fax',array('maxlength'=>255,'class'=>'text-align-left-dir-ltr','style'=>'width:100%','tabindex'=>'8')); ?>
</div>
<div class="msg-error"><?php echo $form->error($model,'fax'); ?></div>
</li>
</ul>
</fieldset>
<fieldset>
<ul>
<li class="text-field span8 text-align-right-dir-rtl tahoma-font-12">
<b><?php echo CHtml::encode($model->getAttributeLabel('googleMap')); ?></b>
<div class="input-prepend">
<?php echo $form->textArea($model,'googleMap',array('rows'=>5,'class'=>'text-align-left-dir-ltr','style'=>'width:100%','tabindex'=>'10')); ?>
</div>
<div class="msg-error"><?php echo $form->error($model,'googleMap'); ?></div>
</li>
</ul>
</fieldset>
<div class="border-line"></div>
<fieldset>
<ul>
<li class="text-field span4 text-align-right-dir-rtl tahoma-font-12"></li>
<li class="text-field span4 text-align-right-dir-rtl tahoma-font-12">
<b><?php echo CHtml::encode($model->getAttributeLabel('active')); ?></b>
<div class="input-prepend">
<?php
echo $form->dropDownList(
$model,
'active',
$model->getTypeOptionsOnline(),
array(
'style'=>'width:50%',
'tabindex'=>'11'
)
);
?>
</div>
<div class="msg-error"><?php echo $form->error($model,'active'); ?></div>
</li>
</ul>
</fieldset>
<fieldset>
<ul>
<li class="text-field span8 text-align-right-dir-rtl tahoma-font-12">
<b><?php echo CHtml::encode($model->getAttributeLabel('offlineText')); ?></b>
<div class="input-prepend">
<?php echo $form->textField($model,'offlineText',array('maxlength'=>255,'class'=>'text-align-right-dir-rtl','style'=>'width:100%','tabindex'=>'12')); ?>
</div>
<div class="msg-error"><?php echo $form->error($model,'offlineText'); ?></div>
</li>
</ul>
</fieldset>
<div class="border-line"></div>
<?php
echo CHtml::submitButton(
CHtml::encode('ذخیره ی اطلاعات'),
array('class'=>'sendmail alignright','tabindex'=>'13')
);
?>
<div>
<a href="javascript:history.go(-1)" title="<?php echo CHtml::encode('بازگشت به صفحه ی قبل'); ?>" >
<?php echo CHtml::image(Yii::app()->request->baseUrl.'/images/icons/for_button/go-back-icon.png'); ?>
</a>
</div>
<?php $this->endWidget(); ?>
</div>
</div>
کد بخش کنترولر : اکشن update
public function actionInfoUpdate($id)
{
$model=$this->loadModel($id);
// Uncomment the following line if AJAX validation is needed
$this->performAjaxValidation(array($model));
if(isset($_POST['Info']))
{
$model->attributes=$_POST['Info'];
$this->valid=$model->validate();
if($this->valid)
{
$this->transaction=yii::app()->db->beginTransaction();
try
{
$_POST['Info']['siteLogo'] = $model->siteLogo;
$_POST['Info']['siteFavicon'] = $model->siteFavicon;
$this->uploadedSiteLogo=CUploadedFile::getInstance($model ,'siteLogo');
$this->uploadedSiteFavicon=CUploadedFile::getInstance($mo del,'siteFavicon');
$model->save(false);
if(!empty($this->uploadedSiteLogo) && !empty($this->uploadedSiteFavicon)) // check if uploaded file is set or not
{
$this->uploadedSiteLogo->saveAs(Yii::app()->request->baseUrl.'/images/logo-icon-site/'.$model->siteLogo);
$this->uploadedSiteFavicon->saveAs(Yii::app()->request->baseUrl.'/images/logo-icon-site/'.$model->siteFavicon);
}
$this->transaction->commit();
$this->redirect(array('infoView','id'=>$model->id));
}
catch(Exception $e)
{
$this->transaction->rollBack();
$this->message=false;
}
}
}
$this->render('infoUpdate',array('model'=>$model,'message'=>$this->message));
}
MMSHFE
شنبه 25 بهمن 1393, 08:51 صبح
آقای شهرکی اگر mime ها رو چک کنیم کافی نیست؟
MIME Type از روی پسوند تشخیص داده میشه مگه اینکه از کلاسهای مخصوصی که هدر فایل رو میخونن استفاده کنید. توی اینترنت درمورد Get MIME type from file header with PHP جستجو کنید. ضمناً ممکنه کدهای مخرب لابلای تصویر درج شده باشن که در اونصورت چک کردم MIME Type هم فایده ای نداره.
Veteran
شنبه 25 بهمن 1393, 09:08 صبح
alirezara
برای متن هایی که استاتیک هستند ( خودتون مینویسید و مستقیم در کد هست) نیاز نیست encode کنید!!!!!! چه کاریه اخه!!!
engmmrj
شنبه 25 بهمن 1393, 19:20 عصر
MIME Type تو yii با استفاده از fileinfo چک میشه و fileinfo ها از رو header فایل چک میکنه که میشه امنیت آپلود را تضمین کرد.
MMSHFE
شنبه 25 بهمن 1393, 20:09 عصر
مطمئنید؟ یکبار فایل bmp رو rename کنید و با پسوند jpg آپلود کنید ببینید $file->type چی چاپ میکنه. ضمناً افزونه fileinfo همه جا نصب نیست. ضمن اینکه همونطور که گفتم، استناد به هدر هم ممکنه درصورت تسلط کافی فرد خرابکار به نحوه درج کد توی عکس، کارساز نباشه. امن ترین روش همون آپلود با GD هست.
engmmrj
شنبه 25 بهمن 1393, 20:22 عصر
مطمئنید؟ یکبار فایل bmp رو rename کنید و با پسوند jpg آپلود کنید ببینید $file->type چی چاپ میکنه. ضمناً افزونه fileinfo همه جا نصب نیست. ضمن اینکه همونطور که گفتم، استناد به هدر هم ممکنه درصورت تسلط کافی فرد خرابکار به نحوه درج کد توی عکس، کارساز نباشه. امن ترین روش همون آپلود با GD هست.
تست کردم وقتی rename میکنی فایل رو قبول نمکنه و از MIME Type ایراد میگیره
Tarragon
شنبه 25 بهمن 1393, 21:09 عصر
سلام
کدم کامل شد.
خدمت دوستان :
controller :
public function actionCreate()
{
$model=new Ads;
$this->layout = '//layouts/column1';
$images = array();
if(isset($_POST['Ads']))
{
$model->attributes=$_POST['Ads'];
$criteria = new CDbCriteria();
$criteria->order = "`id` DESC";
$criteria->limit = 1;
$isId = Ads::model()->findAll($criteria);
if(!isset($isId[0]))
$isId = 1;
else
$isId = $isId[0]->id+1;
$images = CUploadedFile::getInstancesByName('images');
$dir = Yii::getPathOfAlias('webroot').'/images/'.$isId;
if (isset($images) && count($images) > 0)
{
if(!is_dir($dir))
{
mkdir($dir);
}
$i = 0;
foreach ($images as $image => $pic)
{
if($i++ > 3){break;}
if(in_array($pic->getType(), array('image/jpeg','image/gif','image/png')))
{
if ($pic->saveAs($dir.'/temp'.$pic->name))
{
$model->save();
$file = $dir.'/temp'.$pic->name;
$img = Yii::app()->simpleImage->load($file);
$nf = $i.'.jpg';
if($img->getHeight() > 800 || $img->getWidth() > 800)
{
$img->resizeToWidth(800);
}
$img->save($dir.'/'.$nf);
$img->createThumbnail($dir.'/thumbnail_'.$nf);
unlink($file);
$img_add = new AdsImages();
$img_add->photo_name = $nf;
$img_add->ads_id = $model->id;
$img_add->save();
}
else
{
Yii::app()->user->setFlash('error',"لطفا دوباره امتحان کنید.");
$this->redirect();
}
}else{
Yii::app()->user->setFlash('error',"عکس \"". $pic->name."\" غیر قابل قوبل است.");
$this->redirect();
}
}
}
if($model->save()){
$this->redirect(array('view','id'=>$model->id));
}
}
$this->render('create',array(
'model'=>$model,
));
}
view:
<?php
$this->widget('CMultiFileUpload', array(
'name' => 'images',
'accept' => 'jpeg|jpg|gif|png', // useful for verifying files
'duplicate' => 'فایل تکراری است!', // useful, i think
'denied' => 'فقط می توانید عکس ارسال کنید.', // useful, i think
'max' => 3,
'htmlOptions' => array('style' =>'color: transparent;', 'multiple' => 'multiple', 'size' => 25 ),
));
?>
و فایل زیر رو هم در پوشه کامپونت بریزید و در کانفیگ لود کنید به طریق زیر :
// application components
'components'=>array(
'user'=>array(
// enable cookie-based authentication
'allowAutoLogin'=>true,
),
...
'simpleImage'=>array(
'class' => 'application.components.CSimpleImage',
),
یا علی
MMSHFE
یک شنبه 26 بهمن 1393, 08:48 صبح
اگه افزونه fileinfo نصب نباشه به مشکل بر میخورین. این لینکها رو بخونین:
http://www.yiiframework.com/doc/api/1.1/CUploadedFile#type-detail
http://www.yiiframework.com/doc/api/1.1/CFileHelper#getMimeType-detail
http://php.net/manual/en/function.finfo-file.php
http://php.net/manual/en/function.mime-content-type.php
http://www.yiiframework.com/doc/api/1.1/CFileHelper#getMimeTypeByExtension-detail
بهتره بجای $file->type از روش CFileHelper::getMimeType($file->tempName) استفاده کنید. البته این روش هم از همون افزونه استفاده میکنه. درواقع اگه افزونه fileinfo موجود نباشه باز میره از روی پسوند میخونه. در کنار تمام اینها هم گفتم اگه طرف واقعاً نفوذگر باشه لازم نیست هدر رو جعل کنه و توی همون فایل عکس با هدر صحیح هم میتونه کدهای خودش رو تزریق کنه.
Tarragon
یک شنبه 26 بهمن 1393, 18:36 عصر
آقای شهرکی، میشه کد جدید رو چک کنید؟
به روش rewrite عمل کردم.
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.