cs346 1 1 ajax-2 integrating javascript, ajax, php and mysql

64
CS346 1 AJAX-2 Integrating Javascript, AJAX, PHP and MySQL

Upload: matthew-simon

Post on 27-Dec-2015

278 views

Category:

Documents


1 download

TRANSCRIPT

CS346 11

AJAX-2

Integrating Javascript, AJAX, PHP and MySQL

CS346 22

Integrating AJAX, PHP and MySQL Ex4_1.php grabs a random entry from DB and

displays it in an empty field(div) Disables the slot if already filled. Clicking a field in Ex4_1.php calls JS function

grabword Grabword runs AJAX

to retrieve a random item from DB and display it in the field or

disable the field if filled

CS346 33

<?php /* ex4_1.php */ ?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>Example 4_1</title><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /><link rel="stylesheet" type="text/css" href="style.css" /><script type="text/javascript" src="functions.js"></script></head><body> <?php

for ($i = 1; $i < 9; $i++){ ?> <div class="dborder" id=<?php echo "dborder$i"; ?>

onclick="grabword (this.id)"></div> <?php

} ?></body></html>

CS346 44

Notable items in ex4_1.php

PHP tags with a for statement set up a table with 8 elements, each with a different name

onclick event used to fire AJAX To grab a word from DB table block randomly Populate the word into the element clicked

Each element is in a div tag with an id this.id identifies the element clicked.

mysql> show databases;+--------------------+| Database |+--------------------+| information_schema || books || cs346 || mailinglist || mysql || products || testdb1 |+--------------------+7 rows in set (0.14 sec)

From MySQL Console

5

mysql> create database ex04a;Query OK, 1 row affected (0.08 sec)

mysql> show databases;+--------------------+| Database |+--------------------+| information_schema || books || cs346 || ex04a || mailinglist || mysql || products || testdb1 |+--------------------+8 rows in set (0.02 sec)

Create a database in WAMPOn cs346, no need to create a database. Just use the one created for you.

6

mysql> use ex04a;Database changedmysql> create table block ( -> blockid int NOT NULL PRIMARY KEY, -> content varchar(20) -> );Query OK, 0 rows affected (0.27 sec)

mysql> show tables;+-----------------+| Tables_in_ex04a |+-----------------+| block |+-----------------+1 row in set (0.00 sec)

Create a table called block in database ex04a

7

mysql> describe block;+---------+-------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+---------+-------------+------+-----+---------+-------+| blockid | int(11) | NO | PRI | NULL | || content | varchar(20) | YES | | NULL | |+---------+-------------+------+-----+---------+-------+2 rows in set (0.00 sec)

Check the schema

8

mysql> insert into block values (1, 'frying');Query OK, 1 row affected (0.02 sec)

mysql> insert into block values (2, 'awaits');Query OK, 1 row affected (0.00 sec)

mysql> insert into block values (3, 'similar');Query OK, 1 row affected (0.00 sec)

mysql> insert into block values (4, 'invade');Query OK, 1 row affected (0.00 sec)

mysql> insert into block values (5, 'profiles');Query OK, 1 row affected (0.02 sec)

mysql> insert into block values (6, 'clothes');Query OK, 1 row affected (0.00 sec)

mysql> insert into block values (7, 'riding');Query OK, 1 row affected (0.00 sec)

mysql> insert into block values (8, 'postpone');Query OK, 1 row affected (0.00 sec)

INSERT the entries

9

mysql> select * from block;+---------+----------+| blockid | content |+---------+----------+| 1 | frying || 2 | awaits || 3 | similar || 4 | invade || 5 | profiles || 6 | clothes || 7 | riding || 8 | postpone |+---------+----------+8 rows in set (0.00 sec)

Query the table with a SELECT statement

10

Sequence of events

Ex4_1.php displays 8 fields On clicking any field, grabword() in functions.js

is called If field is empty, run AJAX call to

wordgrabber.php to fill it, otherwise blank the field

wordgrabber.php queries the database $querystr = "SELECT content FROM block

ORDER BY RAND() LIMIT 1";

11

Running ex4_1.php

12

CS346 1313

Ex4_1.php

onclick

Javascript function grabword(id)

wordgrabber.php

include dbconnector.php

call opendatabase()

dbconnector.php

define connection variables

function opendatabase()

Ajax

CS346 1414

JavaScript function grabword(element_id) grabword accepts the current object’s id grabword function is in an external JavaScript

file An XMLHttpRequest object xmlhttp has been

created Run an Ajax request to

either populate an empty box Or make the box empty if already populated

CS346 1515

function grabword (theelement){

//If there is nothing in the box, run AJAX to populate it. if (document.getElementById(theelement).innerHTML.length == 0) { //Change the background color. document.getElementById(theelement).style.background = "#CCCCCC";

serverPage = "wordgrabber.php";var obj = document.getElementById(theelement);xmlhttp.open("POST", serverPage);xmlhttp.onreadystatechange = function() {if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { obj.innerHTML = xmlhttp.responseText;}

}xmlhttp.send(null);

} else {//Change the background color.document.getElementById(theelement).style.background = "#FFFFFF";//If the box is already populated, clear it.document.getElementById(theelement).innerHTML = "";}

}

CS346 1616

<?php // wordgrabber.php

// Require in the database connection.require_once ("dbconnector.php");

// Open the database.$db = opendatabase();

// Then perform a query to grab a random word from DB table block// ORDER BY RAND() combined with LIMIT to select a random sample// from a set of rows:$querystr = "SELECT content FROM block ORDER BY RAND() LIMIT 1";

if ($myquery = mysql_query ($querystr)) {$mydata = mysql_fetch_array ($myquery);echo $mydata['content'];

} else {echo mysql_error();

}

?>

CS346 1717

<?php //dbconnector.php

//Define the mysql connection variables. define ("MYSQLHOST", "localhost"); define ("MYSQLUSER", "huen"); // DB username= email username define ("MYSQLPASS", "student_id"); // id without leading 0 define ("MYSQLDB", "huen"); // assigned DB=email username

04/19/23CS346 Fall 2007 CS346 18

//dbconnector.php continued

function opendatabase() { $db = mysql_connect (MYSQLHOST, MYSQLUSER, MYSQLPASS); try {

if (!$db){ $exceptionstring = "Error connection to database: <br />"; $exceptionstring .= mysql_errno() . ": " . mysql_error(); throw new exception ($exceptionstring);} else { mysql_select_db (MYSQLDB,$db);

}return $db;

} catch (exception $e) {echo $e->getmessage();die();

} }?>

CS346 1919

Notable about dbconnector.php Proprietary DB login information located in

only one place Security protection Easy to administer

Provides DB connection and selection of DB Exception handling of DB connection

Displays error number and error message

CS346 2020

Important Design precautions in DB access Avoid overloading the DB

Each click generates an AJAX request to the DB Consider consequences of 3 accesses/per user for a busy

site Ergonomics of loading DB result

If you have a DB error message, it may spill over the enclosure

AJAX tends to load content into small compact space Solution? Email error message to administrator but only a

small message to the user

CS346 2121

Important Design precautions in DB access Security

Perhaps Ajax more vulnerable than full-on-page rendered scripts

Javascript is visible and may be sniffed out GET requests may introduce code injection – SQL

injection

CS346 2222

SQL Injection

SQL Injection Passing malicious code into the query string to

cause problems with any dynamic queries Precaution about the query string!!

mysql_real_escape_string Wrap variables from query string with addslashes

function for string variables intval function (for integer bases variables)

CS346 2323

SQL Injection Example 1 http://www.tizag.com/mysqlTutorial/mysql-php-sql-injection.php

// a good user's name $name = "timmy"; $query = "SELECT * FROM customers WHERE username = '$name'"; echo "Normal: " . $query . "<br />";

// user input that uses SQL Injection $name_bad = "' OR 1'"; // Note the double quotes and single quotes// our MySQL query builder, however, not a very safe one $query_bad = "SELECT * FROM customers WHERE username = '$name_bad'"; // display what the new query will look like, with injection echo "Injection: " . $query_bad;

A sample string gathered from a normal user and a bad user trying to use SQL Injection. We asked the users for their login, which will be used to run a SELECT statement to get their information.

MySQL & PHP Code:

CS346 2424

What actually gets built in SQL query?

Normal: SELECT * FROM customers WHERE username = 'timmy'Injection: SELECT * FROM customers WHERE username = '' OR 1''

Normal query is fine - select everything from customers that has a username equal to timmy as intended.

BUT the injection attack made the query behave differently than intended. • By using a single quote (') the string part of our MySQL query is ended• username = ' ' • an OR clause of 1 (always true) is added on to our WHERE statement with username = ' ' OR 1

This OR clause of 1 will always be true and so every single entry in the "customers" table would be selected by this statement!

CS346 2525

More Serious SQL Injection Attackshttp://www.tizag.com/mysqlTutorial/mysql-php-sql-injection.phpMySQL & PHP Code:$name_evil = "'; DELETE FROM customers WHERE 1 or username = '"; // our MySQL query builder really should check for injection

$query_evil = "SELECT * FROM customers WHERE username = '$name_evil'"; // the new evil injection query would include a DELETE statement echo "Injection: " . $query_evil;

SELECT * FROM customers WHERE username = ' '; DELETE FROM customers WHERE 1 or username = ' '

Resulting Query:

This query with the injected DELETE statement, when run, would completely empty your "customers" table.

CS346 2626

How do we avoid this SQL injection? Injection Prevention -

mysql_real_escape_string() use function mysql_real_escape_string.

takes the string as argument in a MySQL query returns the same string with all SQL Injection

attempts safely escaped. Replaces quotes(') a user might enter with a MySQL-

safe substitute, an escaped quote \'.

CS346 2727

Retry the previous SQL Attack 1$name_bad = "' OR 1'";

$name_bad = mysql_real_escape_string($name_bad);

$query_bad = "SELECT * FROM customers WHERE username = '$name_bad'";

echo "Escaped Bad Injection: <br />" . $query_bad . "<br />";

MySQL & PHP Code:

Resulting Query

Escaped Bad Injection:SELECT * FROM customers WHERE username = '\' OR 1\''

The DB will just search for a ridiculous username \' OR 1\'

Harm avoided.

CS346 2828

Retry the previous SQL Attack 2$name_evil = "'; DELETE FROM customers WHERE 1 or username = '"; $name_evil = mysql_real_escape_string($name_evil); $query_evil = "SELECT * FROM customers WHERE username = '$name_evil'"; echo "Escaped Evil Injection: <br />" . $query_evil;

MySQL & PHP Code:

Resulting query

Escaped Evil Injection:SELECT * FROM customers WHERE username = '\'; DELETE FROM customers WHERE 1 or username = \''

Username is the whole string

\'; DELETE FROM customers WHERE 1 or username = \'

CS346 2929

Calendar example with Ajax and database

Continue with the Calendar example

CS346 3030

1. Create a DB table

mysql> CREATE TABLE task ( -> taskid INT AUTO_INCREMENT PRIMARY KEY, -> userid INT, -> thedate DATE, -> description TEXT -> );Query OK, 0 rows affected (0.06 sec)

CS346 3131

Check

mysql> describe task;+-------------+---------+------+-----+---------+----------------+| Field | Type | Null | Key | Default | Extra |+-------------+---------+------+-----+---------+----------------+| taskid | int(11) | NO | PRI | NULL | auto_increment || userid | int(11) | YES | | NULL | || thedate | date | YES | | NULL | || description | text | YES | | NULL | |+-------------+---------+------+-----+---------+----------------+4 rows in set (0.01 sec)

CS346 3232

Use PHP scripts to create, insert and display DB table in CSlabserv1

Re-use the earlier PHP scripts for creating tables, inserting, displaying contents, drop DB and drop tables, now in a directory db

CS346 3333

Creating a database table task with scripts in cslabserve1/huen/db

CS346 3434

Note: don’t enter a field length for date and int. It will lead to an error for date and restrictive for int.

CS346 3535

List tables in database huen

CS346 3636

Insert records into table task

Response

CS346 3737

CS346 3838

CS346 3939

CS346 4040

CS346 4141

Query the tasks in Calendar

CS346 4242

Create another table user

CS346 4343

CS346 4444

Adding entries to DB table user

CS346 4545

Add another user John Doe to user

CS346 4646

Displaying contents of DB table user

CS346 4747

2. Use dbconnector.php

The PHP scripts keep repeating the DB connection script

Put the connection in one file dbconnector.php

Include this in any application where you need to access database

Your code just refers to $db

CS346 4848

<?php //dbconnector.php //Define the mysql connection variables. define ("MYSQLHOST", "localhost"); define ("MYSQLUSER", "huen"); // DB username= email username define ("MYSQLPASS", "student_id"); // id without leading 0 define ("MYSQLDB", "huen"); // assigned DB=email username

function opendatabase() { $db = mysql_connect (MYSQLHOST,MYSQLUSER,MYSQLPASS); try {

if (!$db){ $exceptionstring = "Error connection to database: <br />"; $exceptionstring .= mysql_errno() . ": " . mysql_error(); throw new exception ($exceptionstring);} else { mysql_select_db (MYSQLDB,$db);

}return $db;

} catch (exception $e) {echo $e->getmessage();die();

} }?>

CS346 4949

3. Modify autocomplete.php Instead of static array in autocomplete.php, use DB access LIKE and NOT LIKE have two search helper symobls.

underscore _ character that looks for one character percentage % character that looks for zero or more

characters. $sql = mysql_query("SELECT * FROM table_name WHERE

columnname LIKE value%");

while ($row = mysql_fetch_row($sql)) {echo "$row[0] $row[1] $row[2] <br />";}

The query will only pick out the rows that provide a TRUE result according to the WHERE equation. The equation will equal the LIKE VALUE plus some possible extra characters afterwards.

CS346 5050

Example of LIKE$sql = mysql_query("SELECT * FROM address_book WHERE last_name LIKE 'Stan%'");

while ($row = mysql_fetch_row($sql)) {echo "$row[0] $row[1] $row[2] <br />";}

Search the address_book table and compare all of the data in the last_name column for any values starting with 'Stan' and ending with zero or more characters afterwards. The LIKE search is not case sensitive, so it will accept anything starting with 'stan' as well. The WHILE loop then prints out the results found if both equations are found TRUE.

CS346 5151

3. Modify autocomplete.php

<?php

//autocomp.php

//Add in our database connector.require_once ("dbconnector.php");//And open a database connection.$db = opendatabase();

$foundarr = array ();

//Setup the dynamic query string.$querystr = "SELECT name FROM user WHERE name LIKE LOWER('%" . mysql_real_escape_string ($_GET['sstring']) . "%') ORDER BY name ASC";

Protect yourself with mysql_real_escape_string

CS346 5252

autocomplete.php modification cont’dif ($userquery = mysql_query ($querystr)){

while ($userdata = mysql_fetch_array ($userquery)){if (!get_magic_quotes_gpc()){

$foundarr[] = stripslashes ($userdata['name']);} else {

$foundarr[] = $userdata['name'];}

}} else {

echo mysql_error();}

See get_magic_quotes_gpc() in PHP manual and example

mysql_real_escape_string

CS346 53

mysql_real_escape_string — Escapes special characters in a string for use in a SQL statementSyntax:string mysql_real_escape_string ( string $unescaped_string [, resource $link_identifier ] )

Description:Escapes special characters in the unescaped_string , taking into account the current character set of the connection so that it is safe to place it in a mysql_query(). If binary data is to be inserted, this function must be used.

mysql_real_escape_string() calls MySQL's library function mysql_real_escape_string, which prepends backslashes to the following characters: \x00, \n, \r, \, ', " and \x1a.

This function must always (with few exceptions) be used to make data safe before sending a query to MySQL.

Another PHP function: addslashes()

04/19/23 CS346 54

string addslashes ( string $str )

Returns a string with backslashes before characters that need to be quoted in database queries etc. These characters are single quote ('), double quote ("), backslash (\) and NUL (the NULL byte).

mysql_real_escape_string is specific to MySQL.

Addslashes is just a general function which may apply to other things as well as MySQL.

CS346 5555

get_magic_quotes_gpc(PHP 4, PHP 5)get_magic_quotes_gpc — Gets the current configuration setting of magic quotes gpcDescriptionint get_magic_quotes_gpc ( void )Returns the current configuration setting of magic_quotes_gpc Keep in mind that the setting magic_quotes_gpc will not work at runtime. For more information about magic_quotes, see this security section. Return ValuesReturns 0 if magic quotes gpc are off, 1 otherwise.

get_magic_quotes_gpc – security feature

CS346 5656

get_magic_quotes_gpc() example<?phpecho get_magic_quotes_gpc();         // 1 => magic quotes are onecho $_POST['lastname'];             // O\'reillyecho addslashes($_POST['lastname']); // O\\\'reilly

if (!get_magic_quotes_gpc()) {    $lastname = addslashes($_POST['lastname']);} else {    $lastname = $_POST['lastname'];}

echo $lastname; // O\'reilly$sql = "INSERT INTO lastnames (lastname) VALUES ('$lastname')";?>

CS346 5757

autocomplete.php modification cont’d//If we have any matches, then we can go through and display them.if (count ($foundarr) > 0){?><div style="background: #CCCCCC; border-style: solid; border-width: 1px; border-color: #000000;">

<?phpfor ($i = 0; $i < count ($foundarr); $i++){

?> <div style="padding: 4px; height: 14px;" onmouseover="this.style.background = '#EEEEEE'" onmouseout="this.style.background = '#CCCCCC'" onclick="setvalue ('<?php echo $foundarr[$i]; ?>')"><?php echo $foundarr[$i]; ?></div><?php }?></div><?php

}?>

CS346 5858

4. Modifying the validator.php<?php

//validator.php

//Add in our database connector.require_once ("dbconnector.php");//And open a database connection.$db = opendatabase();

//Setup the dynamic query string.$querystr = "SELECT userid FROM user WHERE

name = LOWER('" . mysql_real_escape_string ($_GET['sstring']) . "')";

CS346 5959

4. Modifying the validator.php cont’d

if ($userquery = mysql_query ($querystr)){ if (mysql_num_rows ($userquery) == 0){ //Then return with an error. ?><span style="color: #FF0000;">Name not found.</span> <?php } else {

//At this point we would go to the processing script. ?><span style="color: #FF0000;">Form would now submit.</span> <?php }} else { echo mysql_error();}?>

CS346 6060

Autocomplete thru database with Ajax

CS346 6161

Validation through database with Ajax

CS346 6262

5. Modifying taskchecker.php for calendar lookup of taks

<?php

//taskchecker.php

//Add in the database connector.require_once ("dbconnector.php");//Open the database.$db = opendatabase();

//Setup the dynamic query string.$querystr = "SELECT description FROM task WHERE

thedate='" . addslashes ($_GET['thedate']) . "'";

CS346 6363

if ($datequery = mysql_query ($querystr)){if (mysql_num_rows ($datequery) > 0){

?><div style="width: 150px; background: #FFBC37; border-style: solid;

border-color: #000000; border-width: 1px;"><div style="padding: 10px;"><?phpwhile ($datedata = mysql_fetch_array ($datequery)){ if (!get_magic_quotes_gpc()){ echo stripslashes ($datedata['description']); } else { echo $datedata['description']; }}?></div></div>

<?php}

} else { echo mysql_error();}

//Close the database connection.mysql_close ($db);

?>

CS346 6464

Tool tip with database and Ajax