امنیت در PHP - اعتبارسنجی فرم ثبت نام کاربران

امنیت در PHP - اعتبارسنجی در فرم ثبت نام

امنیت در PHP

در این قسمت آموزشی قصد داریم در مورد امنیت در PHP بحث کنیم، لذا برای انجام آن به سراغ ورودی هایی خواهیم رفت که در جلسه قبل به آنها پرداختیم.

در واقع باید کاری کنیم که با وارد کردن اطلاعات در فرم عضویت، قبل از ثبت کاربر در پایگاه داده یک اعتبارسنجی روی داده های ورودی اعمال گردد.

دقت کنید که هکر ها از طریق همین تگ های ورودی به سایت نفوذ کرده و امنیت سایت را به خطر می ندازند که در طی آموزش با بعضی از این راه ها آشنا خواهید شد.

ضمنا اگر اطلاعات به صورت درست وارد شد، در مرحله بعد برای کاربر یک ایمیل تاییده فرستاده شود، و کاربر زمانی مورد تایید نهایی قرار گیرد که لینک موجود در ایمیل را فشار داده باشد. به ادامه مطلب دقت کنید.

همانطور که در قسمت های قبلی دیدید، ما ابتدا جدول داده ای customers را ایجاد و بعد در فایل customer_register.php با استفاده از یک فرم، داده های وارد شده توسط کاربر را دریافت می کردیم.

این داده های ورودی در واقع مقادیری هستند که باید به عنوان مقادیر فیلدهای جدول داده ای customers در نظر گرفته شوند اما تا زمانی که آنها را از لحاظ امنیتی چک نکرده ایم نباید آنها را به جدول داده ای customers اضافه نماییم. برای چک کردن امنیت داده های ورودی از فایل server.php استفاده خواهیم کرد.

ایجاد فایل server.php جهت افزایش امنیت فرم ورود اطلاعات کاربران در PHP

ابتدا باید یک فایل جدید تحت عنوان server.php را در فایل includes ایجاد نمایید. به تصویر زیر نگاه کنید.

ایجاد فایل server.php جهت برقراری امنیت در PHP

حالا به دقت به کدهایی که در فایل server.php  قرار می دهیم، توجه کنید. این کدها همان کدهایی هستند که باید مقادیر ورودی را دریافت و مورد بررسی قرار دهند و در صورت منطبق بودن با استاندارهایی که تعریف کرده ایم، آن مقادیر را وارد پایگاه داده customers کنند. پس حالا فایل server.php را باز کنید و کدهای زیر را در آن قرار دهید.

<?php
	include('db.php');
	// initializing variables
	$c_name = "";
	$c_lastname    = "";
	$c_email    = "";
	$c_address    = "";
	$c_phone    = "";
	$c_password_1 = "";
	$errors = array(); 
	
	// REGISTER USER
	if(isset($_POST['register'])) {
		// receive all input values from the form
		// form validation: ensure that the form is correctly filled ...
		// by adding (array_push()) corresponding error unto $errors array
		
		// receive name value from the form
		$c_name = mysqli_real_escape_string($con , $_POST['c_name']);
		if (empty($c_name)) { array_push($errors, "نام خود را وارد نکردید!"); }
		
		// receive lastname value from the form
		$c_lastname = mysqli_real_escape_string($con ,$_POST['c_lastname']);
		if (empty($c_lastname)) { array_push($errors, "نام خانوادگی خود را وارد نکردید!"); }
		
		// receive gender value from the form
		$c_gender = $_POST['c_gender'];
		if (empty($c_gender)) { array_push($errors, "جنسیت خود را انتخاب نکردید!"); }
		}
?>

در ابتدا سعی می کنیم به پایگاه داده وصل شویم ( include('db.php'); )، چرا که در ادامه باید مقادیر ورودی را در آن ذخیره کنیم. بعد از آن متغییرهایی که در ادامه باید با آنها کار کنیم را مقداردهی اولیه می کنیم.

فقط تنها نکته استفاده از متغییر $errors هست. این متغییر یک آرایه است که اگر کاربر در وارد کردن اطلاعات، از استاندارد های تعریف شده ما تبعیت نکرد، پیام های مناسب را در خود ذخیره کرده و در ادامه به کاربر نمایش داده شود.

حالا به خط کد زیر دقت کنید

	if(isset($_POST['register'])) {

این کد یک شرط است که می گویید: "اگر دکمه (ایجاد نام کاربری) فشار داده شد، آنگاه". دکمه ایجاد نام کاربری همان دکمه ایی است که باید برای ثبت نام توسط کاربر فشار داده شود. به تصویر زیر نگاه کنید.

وقتی دکمه ایجاد نام کاربری فشار داده شود

خب بعد از شرط بالا باید به سراغ ورودی اول برویم. آن را بگیریم و مورد بررسی قرار دهیم. دقت کنید که به طور مشابهی، اقدامات و کدهایی که برای تگ ورودی اول استفاده می شود، برای تگ ورودی دوم نیز استفاده خواهیم کرد. به خط کد زیر دقت نمایید.

		// receive name value from the form
		$c_name = mysqli_real_escape_string($con , $_POST['c_name']);

در اینجا ورودی اول را دریافت می کنیم و با استفاده از تابع mysqli_real_escape_string آن را مورد بررسی امنیتی قرار می دهیم.

تابع mysqli_real_escape_string() جهت امنیت در php چه کاری انجام می دهد؟

کار این تابع این است که اگر در رشته، کاراکتری خاص باشد، اثر منفی آن کاراکتر خاص را از  بین می برد. این کاراکتر های خاص، در واقع کاراکترهایی هستند که ممکنه به امنیت در PHP و پایگاه داده لطمه وارد کنند. هر وقت قرار هست که داده ایی را وارد پایگاه داده کنید، حتما باید از این تابع استفاده شود.

نحوی استفاده و تعریف این تابع هم به صورت زیر هست.

mysqli_real_escape_string(connection,escapestring);
پارامترهای ورودی تعریف
connection این پارامتر باید اتصال به پایگاه داده را برای تابع برقرار کند و وجود آن الزامی است.
escapestring این پارامتر کاراکترهای خاص را از رشته ورودی حذف می کند. به کاراکترهایی که بعد از backslash ها می‌آیند توجه می‌کند:\x00, \n, \r, \, ', " و \x1a. این تابع باید همیشه (به جز چند استثنا) پیش از ارسال Query بهMySQL برای ساخت داده امن استفاده شود.

به خطر افتادن امنیت در PHP با تزریق به پایگاه داده یا SQL Injection

در واقع با استفاده از این تابع ما جلوی حمله ی تزریق به پایگاه داده (به انگلیسی: SQL injection) را خواهیم گرفت.

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

بعد از درک عملکرد تابع mysqli_real_escape_string به شرح ادامه کدهای نوشته شده خواهیم پرداخت. در ادامه کدها متوجه می شوید که یک خط کد به شکل زیر نیز وجود دارد .

		if (empty($c_name)) { array_push($errors, "نام خود را وارد نکردید!"); }

در اینجا نیز با استفاده از تابع empty از خالی بودن یا نبودن اطلاع می یابیم و متناسب با آن پیام خطا را در آرایه $errors قرار می دهیم. در کد بالا 2 تابع استفاده شده است که در زیر آنها را به طور مفصل توضیح داده ام.

تابع empty() در php چه کاری انجام می دهد؟

همانطور که از نام این تابع متوجه شدید کارش این است که ببیند آیا یک متغییر دارای مقدار هست یا خیر. اگر دارای مقدار بود مقدار false را بر می گرداند و اگر متغییر مقدار نداشت true را برگشت می دهد.

دقت نمایید که عملکرد این تابع با تابع isset فرق می کند. تابع isset، وجود یا عدم وجود یک متغییر را چک می کند و کاری به مقدار درون آن متغییر ندارد این درحالی است که تابع empty با مقدار درون یک متغییر سر و کار دارد. برای درک بهتر این موضوع به تصویر زیر دقت نمایید.

تفاوت empty و isset در PHP

تابع array_push() در php چه کاری انجام می دهد؟

کار این تابع این است که مقدار یک یا بیشتر مقادیری را به انتهای یک آرایه اضافه می کند. نحوی استفاده از این تابع هم به صورت زیر می باشد.

array_push(array,value1,value2...)
پارامترهای ورودی تابع شرح
array یک آرایه خاص که مورد نظر شما است و قرار است به انتهای آن مقدار جدید اضافه نمایید. وجود این پارامتر الزامی است.
value1 مقداری است که می خواهید به انتهای آرایه اضافه نمایید. وجود این پارامتر الزامی است.
value2  این پارامتر اختیاری است و بدون این پارامتر هم تابع کار می کند. مقداری است که می خواهید به انتهای آرایه اضافه نمایید.

دو تابع بالا را به طور مفصل برای شما توضیح دادم. با استفاده از توضیحات بالا شما دیگر در درک کدهای ابتدای آموزش مشکل نخواهید داشت. فقط یک نکته باقی مانده است و آن ایجاد فایل errors.php می باشد.

ایجاد فایل errors.php

به آدرس C:\wamp\www\ecommerce\includes بروید و فایل errors.php را در این آدرس بسازید. به تصویر زیر نگاه کنید.

ایجاد فایل errors

حالا باید فایل errors.php را با استفاده از Notepad++ باز کنید و کدهای زیر را درون آن قرار دهید.

<?php  if (count($errors) > 0) : ?>
<div class="error">
  	<?php foreach ($errors as $error) : ?>
	<p><?php echo $error ?></p>
  	<?php endforeach ?>
	</div>
<?php  endif ?>

کدهای موجود در errors.php این را به ما میگویند که اگر خانه های آرایه $errors دارای مقدار باشد، در یک حلقه تکراری، مقادیر خانه های آرایه $errors را برای ما نمایش بده. یادتان هست که زمانی آرایه $errors دارای مقدار است که کاربر اطلاعات را به صورت نادرست وارد کند.

کاری که در ادامه انجام می دهیم این است که پیام های خطا را به کاربر نمایش دهیم برای انجام اینکار باید فایل errors.php را در فایل customer_register.php فراخوانی (include) کنیم.

برای این منظور به آدرس C:\wamp\www\ecommerce بروید و فایل customer_register.php را با استفاده از Notepad++ باز و کدهای زیر را  درون آن پیدا کنید.

<form action="customer_register.php" method="post" enctype="multipart/form-data" > 
				
   <table align="center">

آنها را پاک کنید و کدهای زیر را به جای آنها قرار دهید.

			<form action="customer_register.php" method="post" enctype="multipart/form-data" > 
				
				
				<?php include('includes/errors.php'); ?>
				
				
				<table align="center">

کار دیگری که باید انجام دهید این است که، فایل style.css را باز کنید و کدهای زیر را به انتهای آن اضافه نمایید، تا پیامها به شکل کادر قرمز رنگی در بالای قسمت ثبت نام ظاهر شوند.

/*  error message for page registry  */
.error{
	background: red;
	padding: 10px;
	font-size: 20px;
	border-radius: 5px;
	border: 5px dashed white;
}

یک کار دیگه هم باید انجام بدیم و آن include کردن فایل server.php در فایل customer_rejester.php هست بنابراین فایل customer_rejester.php را باز کنید و کد خط زیر را در ابتدای آن قرار دهید.

<?php include('includes/server.php') ?>

حالا دیگر کار ما با 3 ورودی اول (گرفتن نام و فامیل و جنسیت و بررسی آنها از لحاظ امنیتی) تمام شده است. کدها با توجه به توضیحات بالا به سادگی قابل فهم هستند.

البته یک تغییر کوچک باید در فایل customer_rejester.php بدیم. فایل customer_rejester.php را باز و کدهای زیر را پیدا کنید.

				<tr>
					<td colspan="3" >
						<b style="font-family:b nazanin;font-size:18px;">جنسیت  :  </b>
					</td>
					<td colspan="3" >
						<select name="c_gender" >
							<option >جنسیت مورد نظرتان را انتخاب نمایید.</option>
							<option value="مرد" >مرد</option>
							<option value="زن" >زن</option>
						</select>
					</td>
				</tr>

آنها را پاک کنید و کدهای زیر را به جای آن قرار دهید.

					<tr>
						<td colspan="3" >
							<b style="font-family:b nazanin;font-size:18px;">جنسیت  :  </b>
						</td>
						<td colspan="3" >
							<select name="c_gender" >
								<option value="0">جنسیت مورد نظرتان را انتخاب نمایید.</option>
								<option value="مرد" >مرد</option>
								<option value="زن" >زن</option>
							</select>
						</td>
					</tr>

یک بار با هم چک می کنیم که آیا به درستی سایت نمایش داده می شود. به این منظور بعد از روشن کردن wamp در مرورگر خودتان آدرس http://localhost/ecommerce/customer_register.php را وارد نمایید تا تصویر زیر دیده شود.

رفتن به آدرس customer_rejester

حالا بدون اینکه مقداری را وارد نمایید بر روی دکمه "ایجاد نام کاربری" فشار دهید. حالا باید تصویر زیر برای شما نمایان شود.

نمایش سایت بعد از اعمال تغییرات و اعتبار سنجی داده های ورودی

اگر به خوبی مطلب بالا را 2 الی 3 بار بخوانید و کد بزنید مطمئنم درک آن برایتان بسیار آسان می شود. انشاالله در قسمت های آینده در مورد بررسی سایر input های ورودی و بحث امنیتی که ما باید در قالب سایت رعایت کنیم ، نکات قابل توجه ی را بیان می کنم. قسمت های آینده را از دست ندهید. موفق باشید.

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری فروشگاه اینترنتی با PHP توصیه می‌کند:
نویسنده شوید
دیدگاه‌های شما (5 دیدگاه)

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

Vahid
12 تیر 1399
سلام نحوه ساخت بخش کوپن رو هم کاش اضافه می کردید

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

محمد رضا
27 خرداد 1399
با سلام ببخشید چطوری میتونم واسه خرید اشتراک تاریخ انقضا بزارم مثلا مهلت اشتراک ۱ ماه باشه بعد از اون پیام بده اشتراک به پایان رسید .

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

Alireza
28 اسفند 1398
سلام، بابت آموزش عالیتون ممنون. یه درخواست دارم، ممکنه این قطعه کد رو با متد PDO بازنویسی کنید. در این قسمت به مشکل برخوردم. [code] $c_name = mysqli_real_escape_string($con , $_POST['c_name']); if (empty($c_name)) { array_push($errors, "نام خود را وارد نکردید!"); } [/code]

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

جهانگیر پچکم
02 فروردین 1399
سلام، بله من توی ایمیلتون به شما جواب دادم.

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

سروش
27 فروردین 1399
سلام من همین کد هارو کپی کردم و همه چی درست هست منتها وقتی فرم خالی هست و سابمیت رو میزنم باز هم اینسرت انجام میشه و یک آیدی اضافه میشه! علت چی میتونه باشه؟!

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

جهانگیر پچکم
05 اردیبهشت 1399
سلام دوست گلم تا قسمت 29 لطفا ادامه بدین تا مشاهده کنید که این مشکل حل میشه. مرسی از نظرتون

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

مری
03 دی 1398
سلام. من کدی مشابه نوشتم و اونو که اجرا میکنم اررور میده. در واقع errors رو نمیشناسه! میشه راهنمایی کنید

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

جهانگیر پچکم
05 دی 1398
سلام، لطفا پیغامی که در error به نمایش گذاشته میشه رو قرار بدید تا بهتر متوجه مشکل شما بشم.

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

محمدرضا جوادی فر
25 تیر 1398
سلام من نمی توانم کاربران را در فروشگاه ثبت نام کنم و بعد از زدن دکمه (ایجاد نام کاربری) خطای زیر نشان داده می شود. لطفا راهنمایی کنید.. ممنون.. Warning: mysqli_num_rows() expects parameter 1 to be mysqli_result, bool given in C:\xampp\htdocs\ecommerce\server.php on line 83

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

جهانگیر پچکم
05 دی 1398
سلام به نظر میرسه که مشکل شما در پایگاه داده ای هست که ایجاد کردید. لطفا یکبار دیگه اونو بررسی کنید.

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

حسین
25 اسفند 1399
کوئری ارسالی به پایگاه داده احتمالا اشتباهه

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.