บทความนี้จะนำเสนอวิธีเข้ารหัสไอดี ที่ส่งผ่านลิงค์รับค่าแบบ GET เพื่อป้องกันการสุ่มดูข้อมูลไอดีคนอื่น ที่ไม่ใช่ของตัวเองกันครับ
สังเกตว่าข้อมูลด้านบนนี้เป็นของ "พนักงานขาย คนที่ 1" เป็นการจำลอง SESSION ที่ LOGIN เข้ามา และในตารางนั้นก็คือข้อมูลลูกค้าของตนเอง เมื่อลองคลิกดู "รายละเอียด" ก็จะพบข้อมูลดังภาพด้านล่างนี้
การรับส่งข้อมูลแบบไม่ได้เข้ารหัส ID จะทำให้สามารถสุ่มเลขไอดีได้เรื่อย เพื่อดูข้อมูลของลูกค้าคนอื่นๆ ได้ ดังนั้นเรามาดูฟังก์ชั่นเข้ารหัสที่จะใช้ป้องกันปัญหานี้กัน
สังเกตว่าเมื่อสุ่มรหัสอื่นๆ จะเห็นข้อมูลของพนักงานคนอื่นได้ด้วย
ดังนั้น ก็ต้องเรียกใช้ฟังก์ชั่นเข้ารหัสข้อมูลก่อนส่งไปในหน้าอื่นๆ
เมื่อลองเอาเมาส์ไปชี้ที่ลิงค์ "รายละเอียด" บน Status bar จะแสดงให้เห็นว่าไอดี ถูกเข้ารหัสไว้แล้ว
เมื่อคลิกเข้าไปดูรายละเอียด จะสังเกตเห็นว่า URL ในส่วนของ id จะถูกเข้ารหัสไว้เรียบร้อย
หากลองสุ่มเปลี่ยน ID เป็นตัวเลขอื่น เมื่อเข้าสู่กระบวนการถอดรหัส จะไม่พบข้อมูล
และเพื่อให้ซับซ้อนอีกนิดหน่อย ผมได้ดัดแปลงให้แสดงการเข้ารหัสแบบสุ่ม คือเมื่อเปิดเข้ามาในแต่ละครั้ง ID ที่ถูกเข้ารหัสจะแสดงต่างกันไป
ท่านใดสนใจก็ลองนำไปใช้งานกันดูนะครับ ถ้าพบข้อผิดพลาดในส่วนหนึ่งส่วนใด รบกวนแจ้งผู้เขียนด้วยนะครับ เพื่อจะได้หาทางแก้ไขให้ใช้งานได้อย่างราบรื่นต่อไป
encrypt_function.php
preview_data_encode.php
และในกรณีที่มีผู้ใช้งานระดับหัว ที่สามารถดูของลูกน้องได้ ก็อาจจะใช้วิธี JOIN sale_id ไปยังข้อมูลผู้ขายรายนั้นเพื่อดูว่ามีหัวหน้าเป็นใคร เพื่อจะได้เพิ่มคำสั่ง WHERE ไอดีหัวหน้าผู้ขายเรคอร์ด ที่ตรงกับ SESSION ของหัวหน้าที่ล็อกอินใช้งาน
PHP CI MANIA - PHP Code Generator
อ้างอิง
สังเกตว่าข้อมูลด้านบนนี้เป็นของ "พนักงานขาย คนที่ 1" เป็นการจำลอง SESSION ที่ LOGIN เข้ามา และในตารางนั้นก็คือข้อมูลลูกค้าของตนเอง เมื่อลองคลิกดู "รายละเอียด" ก็จะพบข้อมูลดังภาพด้านล่างนี้
การรับส่งข้อมูลแบบไม่ได้เข้ารหัส ID จะทำให้สามารถสุ่มเลขไอดีได้เรื่อย เพื่อดูข้อมูลของลูกค้าคนอื่นๆ ได้ ดังนั้นเรามาดูฟังก์ชั่นเข้ารหัสที่จะใช้ป้องกันปัญหานี้กัน
สังเกตว่าเมื่อสุ่มรหัสอื่นๆ จะเห็นข้อมูลของพนักงานคนอื่นได้ด้วย
ดังนั้น ก็ต้องเรียกใช้ฟังก์ชั่นเข้ารหัสข้อมูลก่อนส่งไปในหน้าอื่นๆ
เมื่อลองเอาเมาส์ไปชี้ที่ลิงค์ "รายละเอียด" บน Status bar จะแสดงให้เห็นว่าไอดี ถูกเข้ารหัสไว้แล้ว
เมื่อคลิกเข้าไปดูรายละเอียด จะสังเกตเห็นว่า URL ในส่วนของ id จะถูกเข้ารหัสไว้เรียบร้อย
หากลองสุ่มเปลี่ยน ID เป็นตัวเลขอื่น เมื่อเข้าสู่กระบวนการถอดรหัส จะไม่พบข้อมูล
และเพื่อให้ซับซ้อนอีกนิดหน่อย ผมได้ดัดแปลงให้แสดงการเข้ารหัสแบบสุ่ม คือเมื่อเปิดเข้ามาในแต่ละครั้ง ID ที่ถูกเข้ารหัสจะแสดงต่างกันไป
ท่านใดสนใจก็ลองนำไปใช้งานกันดูนะครับ ถ้าพบข้อผิดพลาดในส่วนหนึ่งส่วนใด รบกวนแจ้งผู้เขียนด้วยนะครับ เพื่อจะได้หาทางแก้ไขให้ใช้งานได้อย่างราบรื่นต่อไป
ตัวอย่างโค้ด PHP ทั้งหมดในบทความนี้
encrypt_function.php
<?php function my_simple_crypt( $string, $action = 'e' ) { // you may change these values to your own $secret_key = 'my@simple#secret-key234'; $secret_iv = 'my@simple#secret-iv345'; $output = false; $encrypt_method = "AES-256-CBC"; $key = hash( 'sha256', $secret_key ); $iv = substr( hash( 'sha256', $secret_iv ), 0, 16 ); if( $action == 'e' ) { $output = base64_encode( openssl_encrypt( $string, $encrypt_method, $key, 0, $iv ) ); } else if( $action == 'd' ){ $output = openssl_decrypt( base64_decode( $string ), $encrypt_method, $key, 0, $iv ); } return $output; } function encrypt($string){ $salting = substr(md5(microtime()),-1) . $string; return my_simple_crypt( $salting, 'e' ); } function decrypt($string){ $encode = my_simple_crypt( $string, 'd' ); return substr($encode, 1); } ?>list_data_encode.php
<?php session_start(); include 'encrypt_function.php'; // Test session $_SESSION['user_id'] = 1; //Booking list from database of sale id #2 $tb_booking = array( array( "id" => 1, "booking_name" => "คุณสมหมาย สายเสมอ", "booking_amount" => 7, "booking_total_price" => 700, "booking_email" => "abcd@gmail.com", "booking_tel" => "0894567895", "sale_id" => 1, ), array( "id" => 2, "booking_name" => "คุณมีสุข สมหวัง", "booking_amount" => 2, "booking_total_price" => 1500, "booking_email" => "wxyz@gmail.com", "booking_tel" => "0801236547", "sale_id" => 1, ) ); $arr_sales = array( "1" => "พนักงานขาย คนที่ 1", "5" => "พนักงานขาย คนที่ 2", "9" => "พนักงานขาย คนที่ 3" ); //FROM SESSION LOGIN $user_id = $_SESSION['user_id']; if(isset($arr_sales[$user_id])){ $session_user_name = $arr_sales[$user_id]; } ?> <!DOCTYPE html> <html lang="th"> <head> <meta charset="utf-8"> <title>ทดสอบการเข้ารหัส-ถอดรหัส ID ก่อนจะนำไปใช้งาน</title> <link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css"> </head> <body> <div class="container"> <div class="panel panel-default"> <div class="panel-heading"> <h3>ทดสอบการเข้ารหัส-ถอดรหัส ID ก่อนจะนำไปใช้งาน</h3> </div> <div class="panel-body"> <table class="table table-list-search"> <thead> <tr> <th>#</th> <th>ชื่อลูกค้า</th> <th>จำนวน</th> <th>ราคา</th> <th>พนักงานขาย</th> <th>รายละเอียด</th> </tr> </thead> <tbody> <?php $no = 0; foreach($tb_booking as $row){ $no++; if(isset($arr_sales[$row['sale_id']])){ $sale_respon = $arr_sales[$row['sale_id']]; }else{ $sale_respon = $row['sale_id']; } $encode = urlencode(encrypt($row['id'])); echo '<tr> <td>'.$no.'</td> <td>'.$row['booking_name'].'</td> <td>'.$row['booking_amount'].'</td> <td>'.$row['booking_total_price'].'</td> <td>'.$sale_respon.'</td> <td><a href="preview_data_encode.php?id='. $encode .'">รายละเอียด</a></td> </tr>'; } ?> </tbody> </table> </div> </div> ผู้ใช้งานขณะนี้คือ : <b><font color="blue"><?php echo $session_user_name;?></font></b> </div> </body> </html>
preview_data_encode.php
<?php session_start(); include 'encrypt_function.php'; //All Booking list from database $tb_booking = array( 1 => array( "id" => 1, "booking_name" => "คุณสมหมาย สายเสมอ", "booking_amount" => 7, "booking_total_price" => 700, "booking_email" => "abcd@gmail.com", "booking_tel" => "0894567895", "sale_id" => 1, ), 2 => array( "id" => 2, "booking_name" => "คุณมีสุข สมหวัง", "booking_amount" => 2, "booking_total_price" => 1500, "booking_email" => "wxyz@gmail.com", "booking_tel" => "0801236547", "sale_id" => 1, ), 3 => array( "id" => 3, "booking_name" => "คุณจริงใจ แสนดี", "booking_amount" => 4, "booking_total_price" => 500, "booking_email" => "lmnop@gmail.com", "booking_tel" => "0502314569", "sale_id" => 5, ), 4 => array( "id" => 4, "booking_name" => "คุณสุขกาย สบายใจ", "booking_amount" => 6, "booking_total_price" => 600, "booking_email" => "qrstuv@gmail.com", "booking_tel" => "0951542365", "sale_id" => 9, ), ); $arr_sales = array( "1" => "พนักงานขาย คนที่ 1", "5" => "พนักงานขาย คนที่ 2", "9" => "พนักงานขาย คนที่ 3" ); $id = isset($_GET['id']) ? decrypt(urldecode($_GET['id'])) : ''; $data = isset($tb_booking[$id]) ? $tb_booking[$id] : array(); if(!empty($data)){ if(isset($arr_sales[$data['sale_id']])){ $sale_respon = $arr_sales[$data['sale_id']]; }else{ $sale_respon = $data['sale_id']; } }else{ $sale_respon = '-'; } //FROM SESSION LOGIN $user_id = $_SESSION['user_id']; if(isset($arr_sales[$user_id])){ $session_user_name = $arr_sales[$user_id]; } $font_color = ''; if($sale_respon != $session_user_name){ $font_color = 'red'; } ?> <!DOCTYPE html> <html lang="th"> <head> <meta charset="utf-8"> <title>ทดสอบการเข้ารหัส-ถอดรหัส ID ก่อนจะนำไปใช้งาน</title> <link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css"> <style> .glyphicon-lg { font-size:4em } .square-box { width:100px; min-height:110px; margin:10px; text-align:center!important; background-color:#676767; padding:20px 0 } .square-box { background-color:#20819e;color:#FFF } </style> </head> <body> <div class="container"> <div class="row"> <div class="col-md-5 toppad pull-left col-md-offset-3 "> <br/> <A href="#" >ผู้ใช้งานขณะนี้คือ : <b><font color="blue"><?php echo $session_user_name;?></font></b></A> <br> <p class=" text-info"><?php echo date('Y-m-d H:i:s');?></p> </div> <div class="col-xs-12 col-sm-12 col-md-6 col-lg-6 col-xs-offset-0 col-sm-offset-0 col-md-offset-3 col-lg-offset-3 toppad" > <div class="panel panel-info"> <?php if(!empty($data)){ ?> <div class="panel-heading"> <h3 class="panel-title"><b><?php echo $data['booking_name'];?></b></h3> </div> <div class="panel-body"> <div class="row"> <div class="col-md-3 col-lg-3 square-box " align="center"> <span class="glyphicon glyphicon-user glyphicon-lg"></span> </div> <div class=" col-md-9 col-lg-9 "> <table class="table table-user-information"> <tbody> <tr> <td>จำนวน :</td> <td><?php echo $data['booking_amount'];?></td> </tr> <tr> <td>ราคารวม :</td> <td><?php echo number_format($data['booking_total_price'],2);?></td> </tr> <tr> <td>อีเมล :</td> <td><?php echo $data['booking_email'];?></td> </tr> <tr> <td>เบอร์โทร :</td> <td><?php echo $data['booking_tel'];?></td> </tr> <tr> <td>พนักงานขายผู้รับผิดชอบ</td> <td><font color="<?php echo $font_color;?>"><?php echo $sale_respon;?></font></td> </tr> </tbody> </table> <a href="list_data_encode.php" class="btn btn-primary">กลับไปยังหน้ารายการ</a> </div> </div> </div> <?php }else{ echo '<h3 style="color:red">ไม่พบข้อมูลไอดีตามไอดีที่ระบุ'.$id.'</h3>'; echo '<a href="list_data_encode.php" class="btn btn-primary">กลับไปยังหน้ารายการ</a>'; } ?> </div> </div> </div> </div> </body> </html>
บทส่งท้าย
นอกจากการเข้ารหัส ID เพื่อป้องกันการสุ่มแล้ว ยังมีอีกวิธีที่ใช้ได้ผลอย่างดีนั่นก็คือ "การเช็คสิทธิ์การเข้าถึงข้อมูลของผู้ใช้ในหน้านั้นๆ"
เช่น การเปิดดูรายการใดๆ จะต้องเช็คว่า Record นั้นเป็นรายการที่อยู๋ในความรับผิดชอบหรือเปล่า คือ ต้องมีฟิลด์ไว้เก็บไอดีของ ตัวอย่างเช่น sale_id เราก็ทำการเพิ่มคำสั่ง WHERE อีกตัวเข้าไปคือ
WHERE id = xx AND sale_id = YOUR_SESSION_ID
และในกรณีที่มีผู้ใช้งานระดับหัว ที่สามารถดูของลูกน้องได้ ก็อาจจะใช้วิธี JOIN sale_id ไปยังข้อมูลผู้ขายรายนั้นเพื่อดูว่ามีหัวหน้าเป็นใคร เพื่อจะได้เพิ่มคำสั่ง WHERE ไอดีหัวหน้าผู้ขายเรคอร์ด ที่ตรงกับ SESSION ของหัวหน้าที่ล็อกอินใช้งาน
WHERE id = xx AND (sale_id = YOUR_SESSION_ID OR table_join.leader_id = YOUR_SESSION_ID )
PHP CI MANIA - PHP Code Generator
โปรแกรมช่วยสร้างโค้ด ลดเวลาการเขียนโปรแกรม เขียนโปรแกรมง่ายและสะดวกขึ้น
สนใจสั่งซื้อราคาสุดคุ้ม >> http://fastcoding.phpcodemania.com/
อ้างอิง
1. A simple two-way function to encrypt or decrypthttps://wppeople.net/blog/a-simple-two-way-function-to-encrypt-or-decrypt-a-string/
2. A simple two-way function to encrypt or decrypt a string
https://nazmulahsan.me/simple-two-way-function-encrypt-decrypt-string/
3. microtime — Return current Unix timestamp with
microsecondshttp://php.net/manual/en/function.microtime.php
4. md5 — Calculate the md5 hash of a string
http://php.net/manual/en/function.md5.php
5. substr — Return part of a string
http://php.net/manual/en/function.substr.php
6. base64_encode — Encodes data with MIME base64
http://php.net/manual/en/function.base64-encode.php
7. base64_decode — Decodes data encoded with MIME base64
http://php.net/manual/en/function.base64-decode.php
8. openssl_encrypt — Encrypts data
http://php.net/manual/en/function.openssl-encrypt.php
9. openssl_decrypt — Decrypts data
http://php.net/manual/en/function.openssl-decrypt.php
10. hash — Genera un valor cifrado con base a un string
http://php.net/manual/es/function.hash.php
ความคิดเห็น
แสดงความคิดเห็น