Presentation is loading. Please wait.

Presentation is loading. Please wait.

Web Application Development Instructor: Matthew Schurr.

Similar presentations


Presentation on theme: "Web Application Development Instructor: Matthew Schurr."— Presentation transcript:

1 Web Application Development Instructor: Matthew Schurr

2 Where are we at?  You now know the syntax of PHP and how to manipulate information using PHP.  Now, we need to learn how to handle HTTP requests using PHP and MVC.  We need to use PHP to generate appropriate HTTP responses and send them to our client’s browser.

3 What else do we need?  As we have seen so far, PHP scripts are executed (from start to finish) each time a page is viewed. Values DO NOT persist through page views.  Ideally, we would like to store variables that do persist in one of several categories: Configuration Variables – these variables persist through all page views across all users forever Session Variables – these variables persist (temporarily) through page views and are specific to a certain user Account Variables – these variables persist through page views and are bound to a particular user account forever

4 Frameworks  A framework provides us with a toolkit for creating powerful web applications using a high level API.  The framework provides (among other things)… Database Access API File System Access API HTTP Request/Response API & Cookies API Simplified Request Routing Sessions and Authentication Views and Layouts Configuration Debugging, Logging, and Error Reporting Tools

5 How do we use a framework?  If you followed the directions in class and you are placing your code in webapp.php, then you are already using a framework!  All of the classes, functions, and constants from the Foundation framework are available for you to use (in addition to the standard PHP library).  To get started, simply start using the classes and functions! (They will be auto-loaded the first time you reference them.)

6 Framework File Structure  /controllers  /models  /layouts  /views  /helpers – custom classes/functions  /static – css, js, images, pdfs, etc.  /webapp.log – all errors will be logged here  /webapp.php – routes (request dispatcher)  /config.php – static configuration variables

7 Useful Constants  FILE_ROOT The absolute path to the directory containing webapp.php  EOL A properly encoded end-of-line symbol (\r\n).

8 Utility Functions  These are functions for commonly used operations that are missing from the standard PHP library. Documentation: ~/vendor/mschurr/framework/src/framework/utility.php escape_html($html) unescape_html($string) to_json($array) from_json($json) len($object) with($object) value($object) array_extend($arr, $arr2) str_limit($value, $limit, $end) str_words($value, $limit, $end) str_finish($value, $cap) str_endswith($string, $needle) str_startswith($string, $needle) str_contains($string, $needle) str_random($length[, $chars])

9 Utility Classes  NullObject Returns NullObject to all property accesses and function calls (similar to Objective-C’s nil)  DefaultArrayMap An array map which returns a default value when accessing a key that does not exist.  ImmutableDefaultArrayMap Immutable version of DefaultArrayMap.  DatabaseChunkIterator Iterates through result set of a database query in chunks, preventing all records from being present in memory simultaneously (also useful for paging).

10 HTML Escaping  Recall from Unit 2 that certain characters have significance in HTML and, if we want a string containing them to render them as text instead of markup, we must escape those characters.  The escape_html($string) function does this.  IMPORTANT: If you output text to the page that originated from user input, you MUST escape it using the escape_html function or your app will be vulnerable to attack. If you store user input in the database (or anywhere else) and then access it later, you still must escape it before outputting it. Be careful that you don’t escape something twice! Why?  come to the security lecture

11 Model-View-Controller for the Web  Recall: MVC is a software design pattern that separates data from visualizations. View (UI) HTML/CSS/JS Controller PHP Model (Data) MySQL User Interaction Update Data Update/Fetch HTTP SQL HTTP

12 Controllers  Controllers are the heart of web applications.  Controller implementations contain methods that will be called based on your routing specs. Usually, these correspond to the HTTP method used. ○ public function get() ○ public function post() However, the routing system allows you to specify ANY method.  You can add your own helper methods and member variables to controllers.

13 Controllers  The controller method should return what you want to display to the end user. This might be…  a View (to display to the user)  an int corresponding to an HTTP error code  a Redirect (or URL ) to send the user to  a File (to transfer to the user)  a string referencing another controller  a raw HTTP Response  null (equivalent to returning the provided Response )

14 Controller API  The Controller class contains references to all of the other framework objects as properties: Request Object : $this->request Response Object : $this->response Database Object : $this->database Document Object : $this->document Session Object : $this->session Auth Object : $this->auth  First, we’re going to go over the routing system.  Then, we’ll look at what these objects provide.

15 Routes  Routes allow us to specify what code should be executed based on the information contained in an incoming HTTP request.  You should specify all of your routes in one file: webapp.php. This provides you with a nice, clean overview of the URLs utilized by application in a single file. You should not include any of your application’s logic in webapp.php; only routes and filters.  If no defined route matches the incoming request, user sees a 404 error page.

16 Routes  When we specify a route, we name a target. The target must be either: A method on a class that inherits from Controller A Closure that takes a Request and a Response as its first two inputs  We can use the following commands to route: Route::any($path, $target) ○ Routes requests of any type to the given path to the target. Route::get($path, $target) ○ Routes GET requests to the given path to the target. Route::post($path, $target) ○ Routes POST requests to the given path to the target.

17 Routing to a Closure  The above code routes all get requests to “/” to the closure.  Your browser will display “HELLO WORLD!” if you visit “/”.

18 Routing to a Controller  When we route to a controller, our target is a string version of the name of the class. Route::get('/', 'ControllerClassName');  By default, the route will call the method on the controller that has the same name as the HTTP method of the incoming request.  In this case, the request would be routed to the public method in the class called get().

19  The class ControllerClassName should be defined in the file: ~/controllers/ControllerClassName.php

20 Routing to a Controller (w/ Path)  We may wish to separate our controllers in to groups by placing them inside of folders in the controllers directory.  We can route to controllers contained in a subdirectory by saying: Route::get('/', 'FolderName.ControllerClassName');  In this case, the class definition should be at: ~/controllers/FolderName/ControllerClassName.php

21 Routing to a Controller Method  If we do not wish to route to the method named get() or post(), we can specify which method we want to route to.  This does not change the path at which the class definition should be located.  Route::get('/cool', 'ClassName@methodName');  Route::get('/test', 'Folder.Class@method');

22 Routing Wildcards  We may wish to route requests to all children (in the directory tree) of a given path to the same controller.  We can do this using wildcards. Route::get('/folder/*', 'ClassName');  Notice that the base (/folder/) would not be matched by the route. If that is not what we wanted, we can just add another route to the same location. Route::get('/folder/', 'ClassName');

23 Routing Variables  We may wish to use variables in our routing path.  For example, we might want to have a page for each user of our application. /user-profile/{user_id}  We don’t want to have to manually add a route for each user in our database (there could be millions).

24  Routing variables will be passed as parameters to the controller method that is the target of the route.  You can have more than one variable in a path.

25  You can also specify an optional path variable. In this case, your controller method must provide a default value.  It is possible to combine mandatory and optional path variables, but only the last path variable can be optional.

26 Filtering Route Variables  We may only want to perform a route if our routing variables match certain constraints.  For example, in /profile/{user_id}, we may only want to route when {user_id} is an integer.  We can do this by using regular expressions to specify constraints for our routing variables. Regular expressions are outside of the scope of this course, but I will provide you with some common ones.

27  Sample Regular Expressions: For Integers: [0-9]+ For Alphabetical: [A-Za-z]+ For Alphanumeric: [A-Za-z0-9]+

28 Filtering Routes  Regular expressions are nice, but we also need something more expressive.  A filter is a closure that takes the request followed by any routing variables as inputs and returns either… true (if the route matches the request) false (if the route does not match the request) integer (HTTP error code to display if the route matches the request but has invalid values for parameters)  Filters can optionally include parameters. The first is the request, followed by any URL variables.

29 Filtering a Group of Routes  We might want to apply a filter to a group of routes (for example, all routes that require a user to be logged in).

30 Routing Error Pages  You can also create clean, custom HTTP error pages if you wish. You can do this by defining a controller for errors. In production mode, syntax and runtime errors create a 500 Internal Server Error page.  The syntax for this is: Route::error($code, $target);  For example: Route::error(404, 'Errors@404');

31 Routing with GET Parameters  You can not use the Route command to route based on GET parameters.  If you want to further route based on GET parameters, you will need to do it internally within your controller or in a filter.  Generally, GET parameters contain data that affects the rendering of the page, but not data that should be used for routing.

32 Routing with GET Parameters  For example, the URL for a user’s profile might be /profile/?id=1. In this case, it is sufficient to make a route to /profile. The controller for /profile can then get the additional information it needs (the user id) from the provided get parameter (or throw an error if id is not set).  Alternatively, we could use the URL /profile/1/ It depends on your preference; there is no right or wrong way. A more search-engine-friendly/user-friendly way would be to use the URL /profile/username/.

33 Configuration  We can set configuration values that will alter how the framework (and thus our application) behaves.  The configuration object is a key-value store that holds information that persists between page views across all users.  You should only store configuration values in the configuration object. Do not use it to cache information or store large amounts of data (there are better ways to do this).

34 Configuration  We will hard-code some configuration values in config.php. Database Connection Information  We can also set and read values dynamically in our controllers. When we set a value in a controller, it will persist until it is overwritten or deleted. NOTE: It is not possible to overwrite the hard-coded values at runtime; attempting to do so throws an Exception.

35 Configuration API

36 File System API  Provides a powerful, elegant syntax for manipulating files.  You can review the documentation in the file: ~/vendor/mschurr/framework/src/framework/filesystem/File.php

37 Database  The class will automatically handle safely connecting to and disconnecting from the database server. You can use the API to issue queries and process the results. Obtain reference from either App::getDatabase() or $this->db on a Controller.  Results are returned as an array of rows.  A row is a map of column names to values. ○ array('COLUMN_NAME' => 'VALUE', …);

38 Database API

39 Database Transactions

40 IMPORTANT!!! Safe DB Usage  ONLY use the query method if the SQL is a constant string (no concatenation). $db->query("SELECT * FROM `users`;");  NEVER create an SQL query using concatenation (whether using query or prepare). Examples: (of what not to do) ○ $db->query(sprintf("SELECT * FROM `users` WHERE `username` = '%s';", $request- >post['username'])); ○ $db->prepare(sprintf("SELECT * FROM `users` WHERE `username` = '%s';", $request- >post['username']));

41 IMPORTANT!!! Safe DB Usage  ALWAYS use prepared statements when the SQL query string is not constant. First, create the statement. The string passed to prepare is a template; it should be a constant, not created by concatenation, which contains placeholders for parts of the query that change. ○ $stmt = $db->prepare('SELECT * FROM `users` WHERE `username` = ?;'); Second, execute the statement you created. This is the point at which you pass in the parameters that will fill in the placeholders (in corresponding order). ○ $res = $stmt->execute($req->post['un']);

42 Error Handling  If you try to access a value that isn’t set, an Exception will be thrown. e.g. $this->request->post['aadgkasdfasdjf'] e.g. $this->request->get[‘asdlksdfsadkf']  If a database query fails, an Exception will also be thrown.  You have two options: Explicitly catch these exceptions and implement your own error handling Ignore the exceptions and use the default error handling

43 Error Handling  All runtime and syntax errors may be handled either explicitly (by your code) or implicitly (by allowing the framework to catch them). Any errors you do not explicitly handle are passed to the framework for implicit handling.  The framework handles errors by… Aborting execution Logging the error in webapp.log Displaying either a detailed stack trace OR a generic internal server error page depending on the app.development configuration variable.  Recommendation: Do not catch runtime errors or exceptions that you are unable to recover from. Allow the framework to handle them so that they will be logged and you will be shown a stack trace.

44 Error Handling: Development

45 Error Handling: Production

46 Request API  If you are routing a closure, $request will be a parameter.  If you are routing to a controller class, the $this->request property will point to the Request object.  If you want to get a reference to the singleton Request from anywhere, call: $request = App::getRequest();

47 Request API: Properties PropertyTypeDescription methodStringHTTP method of the request Examples: GET, POST uriStringFull query string contained in the request Example: /path/to/?key=value pathStringFull path contained in the request Example: /path/to/ secureboolWhether or not the request was made securely (HTTPS) ipStringThe client’s IP address. May be IPv4 or IPv6 hostStringThe host header contained in the request timestampintThe time at which the server received the request UNIX timestamp

48 Request API: Properties PropertyTypeDescription cookie cookies array*HTTP Cookies array('name' => (Cookie) $cookie,…) getarray*HTTP GET Parameters array('name' => 'value', …) post data array*HTTP POST Data array('key' => 'value', …) header headers array*HTTP Headers array('Content-Type' => 'text/html', …) file files array*HTTP Transferred (Uploaded) Files array('input_name' => (File) $file, … ) serverarray*Contains information about server settings.server settings array('key' => 'value', …) *These properties are actually instances of RegistryObject but act like arrays. Access to undefined properties throws an Exception.

49 Response API  If you are routing a closure, $response will be a parameter.  If you are routing to a controller class, the $this->response property will point to the Response object.  If you want to get a reference to the shared Response object from anywhere, call: $response = App::getResponse();

50 Response API: Properties PropertyTypeDescription headersarrayAn array of HTTP Headers attached to the response. Content-Type defaults to text/html. statusintHTTP Status Code. Defaults to 200. documentDocumentAllows you to easily modify the HTML document corresponding to outputted HTML or view (see slides on Document API). If the response content type is not text/html, this property will be null. cookie cookies CookieRegistryAllows you to set cookies (see slides on Cookies API).

51 Response API: Methods  void dump($object1, …) Pretty prints anything passed into the function. Useful for debugging.  void clear() Clears all output and headers (effectively resets the object).  void write(String $string) Appends the provided string to the response body (or response document if HTML/View).

52 Response Object: Functions  void json(array $data) Writes the provided array or array map to the response in JSON format and sends it. Properly handles encoding and content type headers.  void with(View $obj) Manually sets the view for the response object. If your route returns a View, you don’t need to call this function.

53 Quiz: What does this code do?

54 Cookies API: Cookie Object  To create a new cookie: $cookie = new Cookie($name);  To read cookie properties: $value = $cookie['property']; $value = $cookie->property;  To set cookie properties: $cookie['property'] = $value; $cookie->property = $value;

55 Cookies API: Cookie Properties PropertyTypeInformation nameStringthe name of the cookie httponlyboolsend the cookie only over HTTP connections (incl. HTTPS… inaccessible via Javascript) default: true secureboolsend the cookie only over HTTPS connections default: $request->encrypted domainStringthe domain the cookie should be set for default: $request->host pathStringthe path(s) at which the cookie should be available default: / (all paths) expiryintUNIX timestamp at which cookie expires default: 2 weeks from now valueStringthe cookie’s value default: null

56 Cookies API: Reading Cookies  To read all cookies, use: $cookies = $request->cookies; $cookies is an array map of Cookie objects ○ array((string) name => (Cookie) cookie, …)  To read a specific cookie, use: if(isset($request->cookie['name'])) $cookie = $request->cookie['name']; $cookie will be a Cookie object Reads to unset cookie names throw an Exception.  NOTE: Only the name and value properties will be accurate. This is a limitation of HTTP.

57 Cookies API: Setting Cookies  Instantiate a new Cookie object and set the properties you desire. $cookie = new Cookie('name'); $cookie->value = 'value';  Attach the cookie to the response: $response->cookies->add($cookie);  If you change your mind (before the response is sent): unset($response->cookies['name']);

58 Cookies API: Deleting Cookies  To delete a cookie, instantiate a new cookie with the same name. Set an empty (null) value Set an expiration time of -1  And attach the cookie to the response.  For your convenience, two shortcuts have been added to do this for you: Cookies::delete(String $name) Cookies::delete(Cookie $cookie)

59 Cookie Security and Tampering  Recall: Cookies are client side and can be edited or faked by the user to have any properties.  When you set a cookie using the framework, the cookie will be accessible on future requests (provided the user has cookies enabled).  However, if the user tampers with the cookie, the framework will act as if the cookie is not set.  Therefore, you may safely assume that any cookie you read through the framework API has not been tampered with. NOTE: This is not true if you use PHP's $_COOKIE.

60 Sessions: Overview  Sessions store information about a single user that persists through page views.  Sessions are simple key-value stores. You should not store large amounts of data (e.g. files). You can store all native types and all serializable objects.  IMPORTANT: Stored information only persists for as long as the user is active (and for a short period of time afterwards). Session may terminate at any time (e.g. if user clears cookies, if system reclaims session memory)  What might we want to store in a session? The account the user is logged in to. Form data (for forms spanning multiple pages) … and more.

61 Sessions: Use Cases  Assume: data stored in the session will likely be available on the next request, provided the next request occurs soon  Always: check whether or not the data you expected to be present is actually present, and handle accordingly  Don’t Assume: data stored in the session will be stored forever, or that it will be available in the long term (e.g. if the user returns a week later) data stored in the session will always be available on the next request

62 Sessions: Use Case Example  Example Use Case: Multi-Page Forms User fills out first page; entries stored in session User fills out second page; entries stored in session User fills out third page; submits the form ○ Entries from first page and second page (stored in session) combined with entries from third page (POST data) and saved in persistent storage (database) ○ Temporary entries in session are freed  What happens if user tries to fill out second or third page, but session contains no data for the previous page? Redirect the user to start the entire process over again  What happens if user fills out first page, but never comes back? Presumably, we can’t do anything with a half-completed form and we would want to throw out the partial input Eventually their session (containing the partial input) will be garbage collected after a period of inactivity (period may vary based on available memory).

63 Sessions API: Properties PropertyTypeDescription idStringA string that uniquely identifies the user. Changes periodically to prevent fixation. SESSION IDS ARE PASSWORD EQUIVALENTS; DO NOT REVEAL THEM OR STORE THEM IN PLAIN TEXT! authAuthSee the slides on the Auth API. userUser_ProviderSee the slides on the User Provider API. An object representing the logged in user (if logged in) or null (if not logged in). loggedInboolWhether or not the session is logged in to a user account

64 Sessions API: Methods  bool has(String $key) Returns whether or not the session has any data stored for $key.  mixed get(String $key, mixed $default=null) Returns the data for $key (if it exists) or $default if there is no data.  void set(String $key, mixed $value) Sets the data for $key to $value. $value can be an array, primitive data type, or object  void forget(String $key) Purges the data for $key (if it exists).

65 Sessions API: Extra Features  The Session object can also act like an array. if(isset($session['key'])) $value = $session['key']; else $session['key'] = $value; unset($session['key'])  The object also supports magic properties. if(isset($session->key)) $value = $session->key; else $session->key = $value; unset($session->key);

66 User Service Provider  Provides a generic interface for managing user accounts. The default driver, 'db', will store the information in the application’s SQL database. There is also a 'cas' driver that can use the Rice Net ID system.  The service provider interacts with user accounts in aggregate.  You can find a reference at: App::getUserService() $this->users on a Controller

67 User Service Provider  A list of all of the User_Service_Provider methods, and their descriptions, can be found at: ~/vendor/mschurr/framework/src/framework/userservice.php

68 User Provider  Provides a generic interface for interacting with a single user account.  References to User_Provider objects can be obtained from User_Service_Provider factory methods.  If the active user is logged in, the user property on the Session will be a User_Provider object for their account.

69 User Provider

70 Privileges  Privileges are simply integer IDs; you will need to keep track of what IDs you have used and what they represent.  For example, you might decide that privilege ID 1 grants full administrator access. You will need to enforce the privileges in your application logic.

71 Group Service Provider  This API provides a system of managing user privileges by placing users into groups, and then granting privileges to entire groups. For example, you might have an “Administrator” group that has all privileges.  The group service provider interacts with groups in aggregate.  Obtaining a reference: App::getGroupService() groups property on Controller

72 Group Provider  Provides a generic interface for interacting with a single group.  References can be obtained from the Group_Service_Provider factory methods.  An array of references can be obtained from the groups() method on User_Provider. Note: The hasPrivilege() method on User_Provider will take into account the group(s) that the user is a member of.

73 Groups Example

74 Authentication (AUTH) Library  The Auth class provides a powerful, easy to use API for handling and managing user authentication.  You will only need to utilize a small subset of this API; everything else will be implemented for you. You can view the documentation for the complete API in the source code (src/framework/auth.php).  Where can I find a reference to the Auth object? auth property on Session

75 Auth API Properties/Methods  loggedIn Returns whether or not the current session is logged into a user account.  user Returns a pointer to the User_Provider object for the account the current session is logged into, or null if not logged in.  logout() Logs attached session out and invalidates any persistent login tokens.

76 Helper Classes and Functions  You may wish to define your own helper classes and functions.  Place your code in ~/helpers/myfile.php  Use import('myfile') to load the code before you use it. You may safely import the same file multiple times.

77 URL  We would like to be able to represent URLs as objects so that we can easily manipulate them.  We would also like to be able to construct URLs to controllers themselves. If we decide to change the routing URL to a controller, we won’t need to update all of the URLs in our code as well.  The URL framework provides this functionality.

78 URL Class Methods  URL::to($object) returns a URL to $object ( or throws URLException if there is no sensible way to convert $object to a URL).  $object can be: a File or StorageFile object a Closure that is the target of a route a Controller object a URL object (returns the provided URL) a string ○ Controller Reference: 'Folder.Controller@method' ○ File Path: 'file://path/to/file' ○ Absolute URL: 'http://…' or 'https://…' or '//…' ○ Absolute Path: '/users'

79 URL Class Methods  Inside of a layout or view, URL::to($this) will return a URL to the controller that presented the view or layout.  You can use URL::asset('/path') to generate a link to a file in the static folder. URL::asset('/css/main.css') ~/static/css/main.css  You should always use URL::asset to generate links to static files.

80 Redirection  To send the user to a location (represented by a URL object): $url = URL::to('/'); Redirect::to($url);  Any statements after the Redirect statement will still be executed. To prevent this behavior, you can simply return the redirect from the controller. return Redirect::to($url);

81 Email

82 Email (or: Why email sucks)  You can use HTML in emails, but… tags do not work. tags do not work (no external style sheets). tags do not work (no Javascript). CSS is supported by most email clients, but all styles must be placed inside of “style” attributes (yikes!).  If you include any tags or tags… The URLs must be absolute links (no relative paths).  The API does not support attachments (for now), but you can use Swift Mailer directly.Swift Mailer

83 Views and Layouts: An Introduction  Provides an abstraction for repeated parts of our HTML layout  Rather than updating shared components once per page, we can update them once  Makes dynamic page generation simple and fast (e.g. user profiles) Define placeholders for variables that change within the same “class” of pages (e.g. username, bio, hometown, etc.)

84 Layouts vs. Views  Layouts define the general appearance of an entire page in HTML, leaving placeholders in areas where the content changes from page to page.  Views fill in the placeholders, providing the missing information.  You can think of layouts as abstract classes and views as concrete subclasses.

85 Vertical Abstraction  Layout Holds items shared among all pages (header, footer, navigation bar, etc.) Contains abstract placeholders that can be filled in by views (e.g. a content section placeholder)  Views Holds items specific to a particular class of page (e.g. content) and fills in layout placeholders ○ View explicitly declares which layout it inherits from (if any) Contains variables that can be filled in at runtime  User Profile Example

86 Horizontal Abstraction  Include source code of one View into the source code of another. Effectively, embedding one View inside of another. Cannot embed Views that implement a Layout.  Use Case: content specific to more than one class of page, but not to all classes of pages (can’t place in layout) e.g. a generic video displaying YouTube - doesn’t show a video on every single type of page, but it does show a video on more than one

87 File Structure  You have two folders: /views /layouts  The name of a view is determined by its location. Name: Welcome File: /views/Welcome.blade.php Name: BookExchange.ContactInformation File: /views/BookExchange/ContactInformation.blade.php  Layouts work exactly the same, but in the layouts folder.

88 Views  In order to present a view, you need two things: The name of the view The variables you wish to pass to the view  For example: View Name: Blog.Post ○ Defined In: ~/views/Blog/Post.blade.php Variables: ○ title = Hello World ○ body = Isn’t making web applications cool?

89 Presenting a View

90 Defining Views and Layouts  Views (and Layouts) are written in a template language called Blade. They should have the file extension.blade.php  Blade is a mixture of HTML and special syntax including: Functions Control Flow Output Control  Views and Layouts only define what will appear inside of an HTML document’s tag.

91 Blade Syntax

92

93

94

95 Sample Layout ~/layouts/BookExchange/Master.blade.php

96 Sample View ~/views/BookExchange/Home.blade.php

97 Sample Controller

98 CSRF Tokens  IMPORTANT: You must include a token in each of your forms (otherwise your application will be vulnerable). The token must be: Unique to the current user (stored in Session) A long (64-256 character) random string Attached to all forms as a hidden input  Ideally the token is: Unique to each form Recalculated on each successful submission

99 CSRF Tokens  You should only utilize a token in forms that modify the server (POST requests).  When the user submits a form, check whether or not the stored token matches the provided one. If they don’t match, throw an error and don’t modify the server.  Why? This prevents CSRF attacks (come to the security lecture if you want to know more).

100 CSRF API  CSRF::make('name') Returns a long, random user-specific token.  CSRF::check('name', 'value') Checks whether or not the token is correct for current user; returns true or false.

101 CSRF Example

102 Form Validation  Why? The user can set ANY ARBITRARY VALUE in POST data and GET parameters. The user can send values not legal in elements (selection or radio boxes).  How? Directly modifying (or forging) the HTTP request sent to the server.  Assume: Any values received from the user may contain malicious information or illegal data. 99.9% of the time this assumption will be false. Must stop the.1% of users who will try to exploit your app

103 Form Validation  MUST verify server-side that data received is within the constraints of the form Maximum and minimum length Data type Within acceptable range …and so forth.  Example: a selection box with three possible values Possible Values: 1, 2, 3 User can send: “troll”, 4, or nothing  What happens? Will our application crash? Will it write invalid data into our database, or will query fail? Will it have an impact when displaying the data elsewhere?

104 Form Validation  MUST safely handle all information Requires detection of errors or malicious data  How do we detect errors? Assume everything received is invalid Prove (for each input) that the value is valid  After checking all inputs: If you have proved everything valid, OK! If not, throw the data away and display an error.

105 Form Validation  We need to verify that the user’s input is valid.  On error, we want to render the form again. Include an error message (otherwise the user will just see the form again and be confused). Preserve the users input so that they do not need to enter the entire form again – only the parts that are invalid. NOTE: never preserve input for password fields; password will be exposed in HTML source code.

106 Example: Form Validation DEMO

107 POST Limitations  We can not share links to success pages that were generated by POST requests. Example: We just added a blog post and we want to link to it right away. Solution: Redirection  When we refresh a page generated by a POST request, the browser gives a warning about form resubmission. What does this mean? ○ If the form performs an action (i.e. inserting a row into the database), it will be repeated. ○ The message can be annoying. Are there any precautions we should take server-side? ○ Solution: Redirection

108 Redirection  Rather than returning HTML on successful form submissions, we return a redirect.  The redirect sends us to a different URL (using a GET request) which returns the success HTML.  This takes three round trips rather than two but solves both of our issues.

109 Implementing Redirections  What we need to accomplish: Make a “Thanks” handler Add the “/thanks” URL to our routing Set the form to redirect to “/thanks” on success  If we want to include data from the form in our thank you message: We need to store that information somewhere that we can retrieve it on the next request (e.g. the database). We need to include a GET parameter in our redirect URL that tells the “Thanks” handler where to find the data.

110 Example: Simple Redirection DEMO

111 Example: Complex Redirection DEMO

112 CAPTCHAs  These are images that contain randomly generated numbers, letters, and symbols.  In order to perform an action, the user must correctly copy the content in the image into a text field.  These are commonly used to prevent robots and other programs from causing spam or submitting garbage records in forms. Generally used to protect forms that are available to the public (e.g. newsletter subscribe) Unlikely that you would need to protect forms that are available only to logged in users using a CAPTCHA

113 CAPTCHA Example

114 Uploading Files  Security Concerns DO NOT ALLOW USERS TO UPLOAD PHP FILES, OR ANY OTHER TYPE OF FILE THAT COULD BE EXECUTED LOCALLY! BE CAUTIOUS: Don’t copy the user-provided file name directly into the file system. ○ What if “../../webapp.php” is provided as file name? Only allow users to upload images (.png,,jpg,.gif).  Storing Uploaded Files Store uploaded files in the “/static/uploads” directory.

115 Example: File Upload DEMO

116 Pagination  Let’s say we have a large table (10,000 records) that we want to show to our user.  We don’t want to show all 10,000 of them in a single page. We will waste bandwidth and CPU time. Their browser will lag trying to render so much data.  We want to show them the results in pages. You will need to do this in your final project.

117 Pagination  First, we want to calculate the total number of records (efficiently) as $c. SELECT COUNT(*) AS `c` FROM `table`;  Next, if we want to display $n records per page, we need to determine the total number of pages. $total = ($c > 0) ? ceil($c / $n) : 1;  We now need to determine the page the user is currently viewing, $p. This will most likely be a GET parameter. Don’t forget to validate it ( 1 <= $p <= $total ). If $p does not meet constraints, do something sensible (like throw an error).

118 Pagination  We want to execute the query to get the data for the current page. Recall SQL: LIMIT OFFSET, COUNT Our count is always going to be $n. Our offset will be ($p – 1) * $n.  SELECT * FROM `table` LIMIT ($p – 1) * $n, $n;  You will also want to display a page navigator with links that your user can click on.

119 DatabaseChunkIterator API  Provides an easy, efficient way of handling pagination and iteration over large tables Hint: may be helpful for the final project!

120 External Services  Can a web application also be an HTTP client? YES!  Apps can make requests to external servers (Facebook, Twitter, Google, etc.) and retrieve a response that contains data.  We can manipulate the data and then pass it to our own clients, even combining data from multiple sources.

121 HTTP Cross-Service Comm.  HTML is not an ideal language for computer to computer communication. Malformed HTML can be a problem. We are forced to rely on regular expressions or DOM to extract data – these are error prone and complex.  There are markup syntaxes created to provide a regular way of expressing data between programs. XML, RSS, JSON  Let’s learn how to use JSON.

122 What is JSON?  Provides a regular way to express data containing the following types: Maps, Arrays, Strings Floats/Doubles, Integers, Booleans Nulls  Almost every modern language provides a way to parse JSON into a native data structure, and vice versa.

123 What does JSON look like?  JSON looks almost exactly like Python. Maps: {} Arrays: [] Strings: "" Floats: 0.0 Integers: -5 Booleans: true/false Nulls: null  Example: { "name" : "John", "age" : 20, "alive" : true }

124 How can we use JSON and PHP?  array from_json(String $string) Converts a JSON string to a native array. Returns null on failure.  String to_json(array $array) Converts a native array to JSON

125 JSON APIs  We can make our application’s data available to non-human clients by providing a JSON API.  You will need to set the Content-Type header to application/json (response->json does this).

126 JSON API Clients  We can also retrieve information from other online applications using their JSON API.  To do this, we would first issue our HTTP request to the other application.  Then, if the request was successful, we would convert the response body (JSON) to the native array format.

127 The xHTTP Library  The response is an instance of xHTTPResponse (if successful) or null on failure.  Don’t forget to also check the response’s HTTP status code!  Remember that external requests block the thread.

128 xHTTPResponse API PropertyTypeDescription statusintHTTP Status Code headersarray mapHTTP Headers Received bodybinary String The response body… may not be a string for certain types (i.e. images). sizeintThe size of the response body in bytes. typeStringThe response MIME type. cookiesarray mapHTTP Cookies Received timeintThe number of milliseconds the request took.

129 JSON Client Example  Note: The Guzzle HTTP library is also included, which is probably better than xHTTPClient. Documentation: https://github.com/guzzle/guzzlehttps://github.com/guzzle/guzzle

130 Other Protocols  Our application can make requests using protocols other than HTTP/HTTPS.  Common Protocols: SMTP/POP3/IMAP – Emails SSH/SFTP – File Transfers FTP – File Transfers  You can implement classes to make requests over any protocol in your application by writing directly to network sockets. http://us1.php.net/manual/en/book.network.php

131 Example: Finger Protocol  We can use the finger protocol to make a request to the finger server at Rice.  This allows us to retrieve information about students given their network id. Note: Students who opt out of the public directory will not be included in results.

132 Improved Finger  Making requests to an external service is very time consuming  External requests could easily push our page load times to be more than ten seconds long. Users =   External service may also apply rate-limiting.  How can we solve these problems?

133 Improved Finger  Use Multithreading The execution of the script can continue while the request is being made in another thread. Not supported by PHP.  Use Caching We make the external request once and then store the result locally, accessing the locally stored result on subsequent requests (which is much faster). API: ~/vendor/mschurr/framework/src/framework/cache.php

134 Caching: Improved Finger  The first time a particular $netid is encountered, the closure is executed and the result stored.  Subsequent encounters to a $netid will bounce off of the local cache.  Review the Cache API in framework source code.

135 Command Line Applications  Can write command line apps in PHP Execute within the environment of the application e.g. Database, Config, Users, Groups API are all available.  Define commands in cliapp.php using: CLIApplication::listen('command', target);  To run the command (in Terminal): php server.php command …args…

136 Command Line Applications  Target must be either… A Closure that takes a single input, $argv, which holds the arguments passed in the command line and which optionally returns an integer exit status. A CLIApplicationController subclass which has a main method that accepts a single input, $argv, and optionally returns an integer exit status. ○ NOTE: See framework documentation in cli.php for methods and properties available to subclasses.  Observe: These are similar to the main() method in a C program.

137 Example CLI Application


Download ppt "Web Application Development Instructor: Matthew Schurr."

Similar presentations


Ads by Google