- شنبه ۲۳ مرداد ۹۵
- ۱۵:۲۲
آموزش اتصال به پایگاه داده
آموزش برنامه نویسی : آموزش برنامه نویسی PHP
در این بخش با تابع mysql_connect() آشنا می شویم. از این تابع برای اتصال به پایگاه داده Mysql استفاده می شود.
ساختار تابع
mysql_connect(host name, user name, password)
mysql_connect() در صورت موفقیت true را بر می گرداند در غیر این صورت false.
مثال
<?
//the example of MySQL database connection
//connect.php
$continued = mysql_connect("localhost","root","admin");
if ($continued) {
echo ("Connection is succeed")
} else {
echo ("Connection is fail")
}امنیت در PHP
اعتبار سنجی داده های ورودی
برای دریافت اطلاعات کاربری معمولا از فرم استفاده می کنیم. در این فرم، از انواع کنترل ها استفاده می کنیم. کاربر از این کنترل ها برای وارد کردن داده استفاده می کند. بعد از وارد کردن داده ها کاربر معمولا انرا ارسال می کند.
داده ای که کاربر ارسال می کند توسط پارامترهای http انتقال می یابد.
کد زیر یک فرم را می سازد:
-Listing Program: FormSederhana.html-->
<html>
<head>
<title>Simple Form for Age Calculationtitle>
head>
<body>
<form method="post" action="hitungumur.php">
<table width="200" border="0">
<caption>
Please fulfill below:
caption>
<tr>
<td width="46">nametd>
<td width="144">
<input name="nama" type="text" id="nama" />
td>
tr>
<tr>
<td>Birthdaytd>
<td>
<input name="day" type="text" id="umur" size="2" />/
<input name="month" type="text" id="bln" size="2" />/
<input name="year" type="text" id="thn" size="4" />/
td>
tr>
table>
<input type="submit" name="Submit" value="Submit" />
form>
body>
html>
در زیر برنامه محاسبه سن امده است.
// Listing Program: HitungUmur.php
function count_ages($start, $end)
{if( $start != '0000-00-00' and $end != '0000-00-00' ){$timestamp_start = strtotime($start);$timestamp_end = strtotime($end);if( $timestamp_start >= $timestamp_end ) return 0;$start_year = date("Y",$timestamp_start);
$end_year = date("Y", $timestamp_end);
$num_days_start = date("z",strtotime($start));
$num_days_end = date("z", strtotime($end));
$num_days = 0;$i = 0;if( $end_year > $start_year )
{while( $i < ( $end_year - $start_year ) )
{$num_days = $num_days + date("z",
strtotime(($start_year + $i)."-12-31"));
$i++;}}return floor((( $num_days_end + $num_days ) -
$num_days_start)/360);}else
{return 0;
}}$born = $year."-".$month."-".$date;$now = date("Y-m-d");
echo count_ages($born,$now);
?>
در محاسبات بالا، برنامه نویس تابعی به نام count_ages() تعریف کرده که محاسبه را انجام می دهد.
اعتبارسنجی عددی
حالا، فرم را با کد زیر می سازیم:
-Listing Program: FormPemesanan.php-->
<html>
<head>
<title>Order Formtitle>
head>
<body>
<img src="install.png"><font size="+5">Order, Please...font>
<form method="post" action="HitungPesanan.php">
<table width="100%" border="1">
<tr><th>Codeth>
<th>Itemth>
<th>Priceth>
<th>Totalth>tr>
<tr>
<td>0001td>
<td>Keyboardtd>
<td>Rp 1.000,-td>
<td><input name="jumlah" type="text" value=""
size="4" maxlength="4" />td>
tr>
table><br>
<input name="Pesan" type="submit" value="Order" />
form>
body>
html>
حالا کدی می نویسیم تا مقدار کلی که کاربر باید پرداخت کند را حساب کند
// Listing Program: HitungPesanan.php
function Calc_Order($price,$order){
return $pay = $price * $order;
}echo "Total you must pay: ";echo number_format(Calc_Order(1000,$total),2,",",".");?>
اگر کاربر مقدار -20 را وارد کند چه می شود؟ مقدار حساب شده منفی می شود. برای حل این مشکل باید مقدار وارد شده را به عدد صحیح Cast کرد و بعد اعتبار سنجی را روی ان انجام داد. برنامه را به این شکل تغییر می دهیم:
// Listing Program: HitungPesanan.php
function Calc_Order($price,$order){
$order = (int)$order;
if ($order < 1){
return 0;
}return $pay = $price * $order;
}$total = Calc_Order(1000,$total);if ($total > 0){
echo "You must pay: ";echo number_format(Calc_Order(1000,$total),2,",",".");}else{
echo "Order input not valid";}?>
در کد بالا اگر مقدار وارد شده کمتر از یک باشد، سفارش غیر مجاز است. این کار در چند خط از کد که در زیر امده انجام می شود:
if ($order < 1){
return 0;
}
ممکن است سوال کنید چرا جلوی متغیر $order از int استفاده کرده ایم. خب. این یک Cast است که مقدار را به عدد صحیح تبدیل می کند. در واقع تمام پارامترهای ارسالی به صورت رشته اند.
مقادیر عددی
عدد صحیح می تواند به هر چیزی تبدیل شود. مثال زیر را ببینید:
اعتبار سنجی رشته ای
کاربران برای وارد کردن نام خود، ادرس خود و کد پستی خود از ان استفاده می کنند. خطررشته های اعتبار سنجی نشده چیست؟ ساده ترین نمونه وقتی است که با پایگاه داده ارتباط داریم. در مثال زیر خطر عدم اعتبارسنجی رشته ها را در مثالی توضیح می دهیم.
قبل از ان، پایگاه داده ای به نام phpsecurity بسازید. با پرس و جوس زیر جدولی بسازید:
$a = 1234; # decimal
$a = -123; # negative
$a = 0123; # oktal (ekivalen 83 desimal)
$a = 0x1A; # hexadecimal (ekivalen 26 desimal)
?>
بعد فرمی را برای ورودی داده کاربر اماده می کنیم:
<html> <head><title>Cek SQLtitle>head> <body> <form method="post"> Username <input type="text" name="uname"> <br> Password <input type="password" name="pass"> <br> <input type="submit" name="submit" value="kirim"> form>
body>
html>
|
|||||||||||||
|
|||||||||||||
if ($submit or $uname){$conn = mysql_connect('localhost','','') or die(mysql_error());$db = mysql_select_db('phpsecurity');
$sql = "Insert into user (uname,password) values ('".$uname."',md5('".$pass."'))";$q = mysql_query($sql) or die(mysql_error());mysql_close();}?>
|
|||||||||||
فرم لاگین ی با کد زیر می سازیم:
<html>
<head><title>Logintitle>head>
<body>
<form method="post">
Username <input type="text" name="uname">
<br>
Password <input type="password" name="pass">
<br>
<input type="submit" name="submit" value="kirim">
form>
body>
html>
if ($submit or $uname){
$conn = mysql_connect('localhost','','') or
die(mysql_error());
$db = mysql_select_db('phpsecurity');
$sql = "SELECT count(1) as ada FROM user
WHERE uname='".$uname."'
AND password=md5('".$pass."')";
echo $sql."<BR>";
$q = mysql_query($sql) or die(mysql_error());
$r = mysql_fetch_array($q);
$jumlah = $r[ada];
mysql_close();
if ($jumlah > 0){
echo "success enter";
}else{
echo "sorry, wrong pair (username dan password)";
}
}
?>
کد بالا را اجرا و نام کاربری درست را وارد کنید. هنگامی که نام کاربری درست را وارد می کنیم وارد می شود.
حالا برای نام کاربری مقدار زیر را وارد کنید:
نام کاربری: ' or uname != ' and password: ') or password !=('
کاربر با موفقیت وارد سیستم می شود.
به این خاطر با موفقیت لاگین کردید که توانستید از طریق یک کنترل باکس متنی دستور sql را دستکاری کنید:
|
||
|
|
برای رفع این آسیب پذیری دو راه وجود دارد:
· محدود کردن نام کاربری و پسورد به حروف و اعداد
· اعتبارسنجی دقیق
راه اول مجبور کردن کاربر به استفاده از نام کاربری و پسورد حرفی و عددی است. یعنی حروف a-z، A-Z و اعداد 0-9.
کد زیر راببینید:
if ((ctype_alnum($uname) == false) or (ctype_alnum($pass) == false)){
die("Sorry, you must enter
alphanumerik.");
}
کد بالا محتوای متغیر های $uname و $pass را برسی می کند تا ببیند حرفی-عددی است یا نه. اگر یکی از این دو نباشد، اسکریپت متوقف می شود.
کد بالا را می توانید در پروسه چک کردن داده در پایگاه داده قرار دهید:
if ($submit or $uname){
if ((ctype_alnum($uname) == false)
or (ctype_alnum($pass) == false)){
die("Maaf, Anda harus menginputkan alphanumerik.");
}
$conn = mysql_connect('localhost','','')
or
die(mysql_error());
$db = mysql_select_db('phpsecurity');
$sql = "SELECT count(1) as ada FROM user WHERE uname='".$uname."'AND password=md5('".$pass."')";
echo $sql."<BR>";
$q = mysql_query($sql) or die(mysql_error());
$r = mysql_fetch_array($q);
$jumlah = $r[ada];
mysql_close();
if ($jumlah > 0){
echo "Success enter";
}else{
echo "Sorry, wrong pair";
}
}
راه دوم، اعتبار سنجی دقیقی روی داده های کاربر اعمال می کنید.
ورودی ها
منابع ورودی معمولا شامل
· Get
· Post
· Cookie
· متغیر های محیطی سرور
· متغیر های محیطی سیستم
می شود.
معمولا کاربران تازه کار توجهی به منبع ورودی داده نمی کنند. حتی ممکن است تفاوت Get را از Post ندانند. کد زیر راببینید:
ContohGet.php-->
<form method="get"
action="ContohGet.php">
Input
your name: <input type="text"
name="nama"
size="30"><br>
<input type="submit"
name="kirim" value="Send">
form>
if
($kirim){
echo
$nama;
}
?>
کد بالا را اجرا کنید. فرم را پر و ارسال کنید. حالا نوار ادرس را ببینید. می بینید تمام پارامترها و مقادرشان در نوار ادرس ظاهر شده اند:
http://localhost:8004/PhpSecurity/Bab1/ContohGet.php?nama=Ilmia&kirim=kirim
اگر مقادیر پارامترها به این شکل در نوار ادرس ظاهر شود یعنی ما از Get استفاده کرده ایم.
کد زیر از Post استفاده می کند:
ContohPost.php-->
<form method="post"
action="ContohPost.php">
Input
your name: <input type="text" name="nama"
size="30"><br>
<input type="submit"
name="kirim" value="kirim">
form>
if
($kirim){
echo
$nama;
}
?>
مشکل زمانی رخ می دهد که یک پارامتر از بیش از یک منبع ظاهر شود. مثلا، با استفاده از Post یک id اضافه کرده اید. در طرف دیگر id توسط یک کوکی هم ارسال شده است. PHP یکی از این دو را انتخاب می کند. کدامیک؟
راه حل را می توان در فایل php.ini دید. این موضوع توسط gpc_order (برای نسخه های قدیمی PHP) و variables_order (برای نسخه های جدید PHP) کنترل می شود. فایل php.ini را باز کنید و خط زیر را بیابید:
; This directive is deprecated.
; Use variables_order instead.
gpc_order = "GPC"
همانطور که می بینید، مقدار پیش فرض gpc_order برابر GPC است که به معنای Get، Post و Cookie است. مقادیر به ترتیب ضعیف ترین تا قویترین هستند. به این ترتیب اولویت اول کوکی است. در نسخه های جدید PHP از variables_order استفاده می شود:
; This directive describes the order in which
; PHP registers GET, POST, Cookie,
; Environment and Built-in variables (G, P, C, E & S
; respectively, often
; referred to as EGPCS or GPC). Registration is done from
; left to right, newer
; values override older values.
variables_order = "GPCS"
در کد بالا اولویت اول با system/server است، بعد با کوکی، Post و Get.
برای دسترسی به مقدار یم متغیر در یک دامنه خاص (مانند کوکی، Get) از متغیرهای زیر می توانیم استفاده کنیم:
متغیر |
منبع |
$HTTP_COOKIE_VARS |
Cookie |
$HTTP_ENV_VARS |
Environment |
$HTTP_ POST_FILES |
File |
$HTTP_GET_VARS |
Get |
$HTTP_POST_VARS |
Post |
$HTTP_REQUEST_VARS |
Request |
$HTTP_SERVER_VARS |
Server |
$HTTP_SESSION_VARS |
Session |
مشکل فایل
برخی سایت ها اجازه آپلود کردن فایل ها را به کاربران می دهند. مثلا کاربران می توانند عکس های خود را اپلود کنند.
وقتی کاربر اجازه می یابد فایلی را روی سرور آپلود کند، باید مواظب ان باشید. ساده ترین حالت، کنترل اندازه فایل آپلودی است. تصور کنید عکس ارسالی ممکن است از نوع bmp باشد که اندازه بالایی دارد. میزان فضای ازاد سرور چه قدر است. چند کاربر قرار است فایل اپلود کنند؟
اجازه دهید کدی بنویسیم که کار آپلود را انجام می دهد:
<form action="UploadFile.php" method="POST" enctype="multipart/form-data">
File: <input type="file" name="ufile" size="30"><br>
<input type="submit" name="kirim" value="kirim">
form>
if ($kirim){
$uploaddir = $_SERVER['DOCUMENT_ROOT']."/phpsecurity/bab1/";
$uploadfile = $uploaddir .
$_FILES['ufile']['name'];
if (move_uploaded_file(
$_FILES['ufile']['tmp_name'], $uploadfile)) {
echo "Sukses upload";
}else{
print_r($_FILES);
}
}
?>
با کد بالا می توان هر فایلی با هر اندازه ای را اپلود کرد.
در زیر حجم فایل آپلودی را محدود می کنیم:
<form action="SizeFile.php" method="POST" enctype="multipart/form-data">
File: <input type="file" name="ufile" size="30"><br>
<input type="submit" name="kirim" value="kirim">
form>
if ($kirim){
$uploaddir = $_SERVER['DOCUMENT_ROOT']."/phpsecurity/bab1/";
$uploadfile = $uploaddir.$_FILES['ufile']['name'];
$maxsize = 50000;
if ($_FILES['ufile']['size'] > $maxsize){
exit("Your file (" . number_format($_FILES['ufile']['size']/1000,0,',','.') . " kb) exceed limit (50kb).");
}
if (move_uploaded_file($_FILES['ufile']['tmp_name'], $uploadfile)) {
echo "Sukses upload";
}else{
print_r($_FILES);
}
}
?>
همیشه نمی توان به نوع فایل آپلود شده اطمینان کرد. برای اطمینان از اینکه فایل ارسالی عکس است از کد زیر استفاده می کنیم:
<form action="TypeFile.php" method="POST" enctype="multipart/form-data">
File: <input type="file" name="ufile" size="30"><br>
<input type="submit" name="kirim" value="kirim">
form>
if ($kirim){
$uploaddir = $_SERVER['DOCUMENT_ROOT']."/phpsecurity/bab1/";
$uploadfile = $uploaddir . $_FILES['ufile']['name'];
$tipe = $_FILES['ufile']['type'];
if ( ($tipe != "image/pjpeg") or $tipe != "image/png") or ($tipe != "image/gif")){
exit("Tipe file Anda: ". $_FILES['ufile']['type'] .". Silakan mengupload file jpeg/png/gif.");
}
if (move_uploaded_file($_FILES['ufile']['tmp_name'], $uploadfile)) {
echo "Sukses upload";
}else{
print_r($_FILES);
}
}
?>
احراز هویت در HTTP (HTTP Authentication)
حتما به سایت هایی برخورد کرده اید که هنگام باز کردن ان، یک پیغام نمایش داده و از شما نام کاربری و پسورد می خواهد. ماند صفحه اول Cpanel. این صفحات از HTTP Authentication استفاده می کنند.
برای محافظت از صفحه ها با HTTP Authentication، باید دو header را تحویل دهید. WWW-AUTHENTICATE به مرورگر می گوید که به نام کاربری و پسورد نیاز است. header دیگر status است که باید HTTP/1.0 401 Unauthorized باشد. header حالت عادی HTTP/1.0 200 OK است.
مثال. فایلی به نام protectHTTP.php در پوشه www/test/phpsecurity بسازید. کد زیر را وارد کنید:
php
// test for username/password
if(($_SERVER['PHP_AUTH_USER'] == "mia") AND ($_SERVER['PHP_AUTH_PW'] == "secret"))
{
echo("successfully!<br>\n");
}
else
{
//Send headers to cause a browser to request
//username and password from user
header("WWW-Authenticate: " . "Basic realm=\"PHPEveryDay's Protected Area\"");
header("HTTP/1.0 401 Unauthorized");
//Show failure text, which browsers usually
//show only after several failed attempts
print("This page is protected by HTTP ");
}
?>
با مرورگرتان به ادرس http://localhost/test/phpsecurity/protecthttp.php بروید.
اگر مرورگر نام کاربری و پسورد را بفرستد، PHP به طور خودکار دو متغیر PHP_AUTH_USER و PHP_AUTH_PW را در آرایه _SERVER می سازد.
درخواست یک صفحه محافظت شده با HTTP Authentication
در بالا یک صفحه محافظت شده نوشتیم. در اینجا ان صفحه را از درون صفحه ای دیگر باز خواهیم کرد.
php
//open socket
if(!($fp = fsockopen("localhost", 80)))
{
print("Couldn't open socket!<br>\n");
exit;
}
//make request for document
fputs($fp, "HEAD /test/phpsecurity/protecthttp.php HTTP/1.0\r\n");
//send username and password
fputs($fp, "Authorization: Basic " .base64_encode("mia:secret") ."\r\n");
//end request
fputs($fp, "\r\n");
//dump response from server
fpassthru($fp);
?>
در خط 13، نام کاربری و پسورد را اینگونه تغییر دهید:
|
احتمالا پیغامی اینگونه را دریافت می کنید:
|
||
|
|
||
|
لاگین با استفاده از phpSecureLogin
مقدمه
تازه کارید؟ یا وقت نوشتن کد سیستم لاگین را ندارید؟ کلاسی وجود دارد که کمک می کند سیستم لاگین را راحت بسازیم. این کلاس PhpSecureSite است. به راحتی می توانید انرا در سایتتان به کار ببرید.
PhpSecureSite یک سیستم احراز هویت(authentication) و کنترل کننده جلسه (session-handling) است. PhpSecureSite فقط برای استفاده در صفحات وب نوشته شده است. طوری طراحی شده تا کاملا با برنامه تحت وب مجتمع شود، بنابراین باید برای قسمت نمایش ان (مثلا، صفحه لاگین) خودتان کد بنویسید.
برای درک سیستم کنترل کننده جلسه، باید نگاهی به نحوه کار وب سرور داشته باشیم. پروتکل HTTP، یعنی زبان ارتباطی مرورگر و وب سرور، یک پروتکل به اصطلاح stateless است (وضعیت را نگهداری نمی کند). به این معنا که هنگامی که وب سرور درخواستی برای یک صفحه را دریافت می کند، بدون هیچ سوالی، ان صفحه را بر می گرداند. وب سرور نه می داند و نه علاقه ای دارد بداند چه کسی چه صفحه ای را درخواست داده است. کنترل کننده جلسه مشخص می کند کدام کاربر صفحه را درخواست داده است، اینگونه می توان صفحه را برای هر کاربر به صورت پویا و سلیقه ای ساخت.
به وضوح، استفاده اصلی از PhpSecureSite برای کنترل دسترسی به صفحات وب است، اما موارد استفاده دیگری هم دارد. همراه PhpSecureSite ماژول هایی با قابلیت های دسترسی به متغیر های جلسه (متغیر ها یی که برای جلسه ذخیره و در تمام صفحات قابل دسترسی اند)، دسترسی به لیست کنترل (control list) (برای تعیین دسترسی کاربران به صفحه ها) و موارد دیگر، وجود دارد.
این کلاس را می توانید از ادرس ftp://oss.codepoet.no/phpsecuresite/phpsecuresite-0.1.2.tar.bz2 دانلود کنید.