Difference between revisions of "WebFund 2014W Lecture 5"

From Soma-notes
Jump to navigation Jump to search
(Lecture 5 Notes)
 
Line 1: Line 1:
== Video ==
Video from the lecture given on Jan 22, 2014 is now available from multiple sources:
Video from the lecture given on Jan 22, 2014 is now available from multiple sources:
* [http://www.screencast.com/t/Aypl5x4M small at screencast.com] (flash/mp4)
* [http://www.screencast.com/t/Aypl5x4M small at screencast.com] (flash/mp4)
Line 6: Line 8:




• To create an empty object we use:
== Lecture Notes ==
 
  o Var car = { speed: “slow”};
  o Var tesla = object.create(car);
• To check the properties of the object:
  o Tesla.speed
  o ‘slow’
• To assign a different value to the speed property:
  o Tesla.speed  = “fast”;
  o ‘fast’
• To assign a default value to a prototype object property:
  o Car.colour = “white”;
  o ‘white’
• To check:
  o Car
  o { speed: ‘slow’,  colour: ‘white’ }
  o Tesla
  o { speed:  ‘fast’ }
• Note that the object “tesla” does not have the property colour but its prototype has it.
  o Object.getPrototypeOf(tesla);
  o { speed:  ‘slow’,
  o colour: ‘white’
  o wheels: 4 }
• Every object in JavaScript has a prototype that can be accessed by:
  o Object.prototype
• Session-demo:
• Different users have different sessions and the server knows about the different sessions. The server is keeping track of state per user that is logged in.


• The state is a representation of what is on the server but it is also a reflection of which session has been identified to the server.
In this lecture JavaScript object inheritance (the prototype object) is explained.  Along with this an overview of [[WebFund_2014W:_Tutorial_3 | Tutorial 3]] is given which covers sessions, cookies, and some other related material.  Miscellaneous comments and questions asked throughout the class are also present, and are listed in the last section.


• HTTP is a stateless protocol. Stateless means that each request that goes to the browser is independent of every other request.
=== Prototypal Inheritance in JavaScript ===


• When you make a request, your browser does not only send URL. It also sends a request with a lot of other properties. This is also a part of the HTTP protocol.(Look under the “Header” tab of the “Network” section in the Firefox console).
Inheritance in JavaScript is not 'classical' as in other languages such as Python, Java, or C/C++. Instead, each object has a hidden prototype object <code><nowiki>[[Prototype]]</nowiki></code> which is inherited from the parent object's visible <code>.prototype</code> object. By 'hidden', we mean that the object cannot be accessed directly; variables and functions defined in the hidden prototype object are returned if they are accessed/called but haven't been set on the inheriting object. Likewise, by 'visible', we mean that the prototype object appears as a property of the object, with properties which can both be set and used.


• A User-Agent string is a part of the HTTP request. It is supposed to tell the server what kind of browser you are using.  
There are a lot of explanations of how this works on both [http://stackoverflow.com/search?q=javascript+prototype+inheritance stackoverflow], and just generally [https://www.google.ca/search?q=javascript+prototype+inheritance on the internet]. Using the car example as in the lecture, we'll first define the constructor using [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Values,_variables,_and_literals#Object_literals object literal] syntax.  Then, we'll do some experiments and see what happens.  Note that the examples shown below were done in the developer console on Google Chrome Browser version 32.00.


• A cookie is some bit of data that is sent somewhere and is expect to be returned later and is not to be processed or “eaten” by the other side.
> var Car = function () { this.speed = 'slow' };
  undefined
> Car.prototype = {color: 'white'};
  Object {color: "white"}
> var tesla = new Car();
  undefined
> tesla
  Car {speed: "slow", color: "white"}
> tesla.prototype
  undefined
> tesla.hasOwnProperty('color');
  false
> tesla.hasOwnProperty('speed');
  true


• Status code: every HTTP request that comes in to a server will generate a response code. (i.e. response code 200 means o.k. Response code 404 means page not found and 302 means page moved temporarily).
Notice how <code>tesla.prototype</code> does not exist.  When <code>tesla</code> is created as a <code>Car</code> object, it's properties are augmented by the properties in <code>Car.prototype</code>.  Looking closer, we also see that the JavaScript runtime in the Chrome browser 'cheats' by telling us that <code>color</code> is a property of the variable <code>tesla</code>. Using the <code>hasOwnProperty</code> function<sup>[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty  1]</sup> however, we see that <code>color</code> is actually a property of <code>tesla</code>'s prototype. Shown below is the same example using the <code>Object.create</code> function<sup>[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create 2]</sup>, as it was done during class.


• Node is a general web application execution platform. Express is a framework for it.  
> var car = {'color': 'white'};
  undefined
> car
  Object {color: "white"}
> var tesla = Object.create(car);
  undefined
> tesla.speed = 'slow';
  "slow"
> tesla.prototype
  undefined
> tesla.hasOwnProperty('color');
  false
> tesla.hasOwnProperty('speed');
  true
 
<code>Object.create</code> creates a new object, sets its prototype to the passed in argument, and then returns that object.  So in order to actually create the same object as we did in the previous example any variables set in the prototype there would actually have to be set in the car object here. Note that instead of setting the <code>speed</code> of <code>tesla</code> to <code>slow</code> after creation, it can be supplied in the call to <code>Object.create</code>.


• The following function takes ‘Comp 4106 rules!’ as a secret argument to encrypt the user session and to generate the valid cookies. The cookies must be made to be hard to reverse by others.
As we're learning JavaScript, some good reference material would be Douglas Crockford's book 'JavasScript; The Good Parts', as well as his [http://www.yuiblog.com/crockford/ posted videos] on the yuiblog site.
  o app.use(express.cookieParser(‘Comp 2406 rules!’));
The following function uses the cookie parser in order to maintain sessions. It is the session identifier. Every time we do a “get” a cookies comes along with it and the user is identified:
  o app.use(express.session());
• Cookies can be specified with different life times. Some cookies  are specified with session only life time. Some other cookies are specified to live for hours, days or years.




• /routes/Index.js:
=== Tutorial 3 Overview ===


• When the user enters the username, the incoming request has a session sub-object which is defined by the session layer of Express
For this tutorial and any consecutive tutorials the <code>node_modules</code> folder will be provided with the demo code.  Otherwise, modules can be downloaded/installed using the node package manager (<code>npm</code> command) which is installed with node.


• If the session object has a username as a property, the user is already logged in
The tutorial consists of a demo application which simulates a basic login process, complete with cookie-based sessions.  The basic flow is as follows: when a user logs in the server will set some cookies via the response which is sent back to the browser.  Once this occurs the cookies will be sent with every request & response until they expire.  For most cookies this is either when the browser closes, or when a certain length of time has passed.  Dealing with these cookies is done by middleware which is set in the <code>app.js</code> file, as shown below.


  o Function index (req, res) {
25 app.use(express.cookieParser('COMP2406 rules!'));
  o If (req.session.username){
26 app.use(express.session());
  o     res.redirect(“/users”);
  o } else {
  o res.render(‘index’), { title: ‘COMP 2406 Session Demo’,
  o                                   error: req.query.error  });
  o }
  o }


• In the following code we set the username variable by (req.session.username)
For our purposes, all interaction is done with the request's session object (<code>req.session</code>) during routing.  An example of this is shown in <code>index.js</code>, where we test the session object for a <code>username</code>.  If the <code>username</code> exists then we know that we have previously logged the user in, so we render the page.  Otherwise, we redirect them to the home page.  When viewing this process from the developer console in either Firefox or Chrome (or another browser), we'll see [https://en.wikipedia.org/wiki/List_of_HTTP_status_codes http status codes] associated with the requests; either a <code>200 OK</code> or a <code>302 Moved Temporarily</code>.


  o Function login (req, res) {
13 function users(req, res) {
  o Var username = req.body.username;
14    if (req.session.username) {
  o Req.session.username = username;
15        res.render("account.jade", {username:req.session.username,
  o loggedInUsers [username] = LoggedIn;
16            title:"Account",
  o res.redirect (/users”)
17            loggedInUsers: loggedInUsers});
  o }
18    } else {
19        res.redirect("/?error=Not Logged In");
20    }
21 };


• Note that the user name came from the req.body object.
Not only the status codes are shown in the developer's console.  Also shown is more information about any requests; header information (including the user agent string), form/query parameters, cookies, and the actual content of responses.


• (req.body.username) is a part of the form.
The above code snippet also shows us something about Jade. Put simply, it's a template engine; it takes template code and transforms it into html.  What's even more impressive is that we can pass variables to the templates which will be inserted onto the pages when this transformation occurs. This is shown on line <code>15</code> by the call to <code>res.render</code> where we pass in the template file followed by an object of variables.


• The form “post” sends the user name to the server (this can be viewed under the “params” tab of the “network” section in the console.
One last thing which should be also be mentioned is session hijacking.  Consider the situation that we have, where login information is stored in the cookies.  If an adversary was able to guess how our cookies were constructed, then they would be able to fake being a user, and would gain access to the user's account.  To help protect against this the express session module employs cryptographic hashing in order to obfuscate cookies.  This type of hashing can't be reversed, so validity is checked through a re-hashing of supplied data which is compared to an existing hash.


• Next we save it to the session by 
  o Req.session.username = username;


=== Miscellaneous ===


• When you ever see a line like:
;How do we start node?
  o Form (action=”/login” , method=”post”)
:Different linux distributions may call the package different names.  The two most common are <code>node</code>, and <code>nodejs</code>.


In /views/index.jade
;What's the difference between the prototype property and the object's prototype.
You should expect to see a corresponding route like:
:An object's prototype property is just that, a property named <code>prototype</code>. When that object is used as the base class for another object however, the new object will have the hidden <code><nowiki>[[Prototype]]</nowiki></code> property set as the base classes <code>.prototype</code> property. See [http://stackoverflow.com/a/572996 this] StackOverflow answer for more information.
  o App.post(“/login”, routes.login);
  o App.post(“/logout”, routes.logout)
In app.js
Otherwise there will be a 404 error (page not found).


• When deleting
;What's the deal with equality predicates?  Which ones should I be using?
  o App.use(express.json());
:Whenever you're able to, use <code>a === b</code> instead of <code>a == b</code>, etc.  The double equals is able to carry out type coercion, which may be an unintended side effect. In addition to this, there are other small differences in equality checking.
Nothing really happens


;Is there another way to set the object prototype?
:There are a few ways, which are all listed on [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain#Different_ways_to_create_objects_and_the_resulting_prototype_chain this page] in the Mozilla Developer Network Javascript Guide!


• When deleting
;The Comp 2406 virtual machine isn't running well on my machine!
  o App.use(express.urlencoded());
:Well, check out the video lectures starting with this one; if the VM is running slower than the one in class then odds are that your computer is misconfigured.
The (req.session.username) condition in index.js (as shown below) fails and it won’t consider the user logged in.
  o Function users (req, res) {
  o If(req.session.username){
  o res/render (“account.jade”, {username: req.session.username,
  o title:”Account”,
  o loggedInUsers: loggedInUsers});
  o } else {
  o res.redirect(“/?error=Not Logged In”);
  o }
  o };

Latest revision as of 22:19, 5 February 2014

Video

Video from the lecture given on Jan 22, 2014 is now available from multiple sources:


Lecture Notes

In this lecture JavaScript object inheritance (the prototype object) is explained. Along with this an overview of Tutorial 3 is given which covers sessions, cookies, and some other related material. Miscellaneous comments and questions asked throughout the class are also present, and are listed in the last section.

Prototypal Inheritance in JavaScript

Inheritance in JavaScript is not 'classical' as in other languages such as Python, Java, or C/C++. Instead, each object has a hidden prototype object [[Prototype]] which is inherited from the parent object's visible .prototype object. By 'hidden', we mean that the object cannot be accessed directly; variables and functions defined in the hidden prototype object are returned if they are accessed/called but haven't been set on the inheriting object. Likewise, by 'visible', we mean that the prototype object appears as a property of the object, with properties which can both be set and used.

There are a lot of explanations of how this works on both stackoverflow, and just generally on the internet. Using the car example as in the lecture, we'll first define the constructor using object literal syntax. Then, we'll do some experiments and see what happens. Note that the examples shown below were done in the developer console on Google Chrome Browser version 32.00.

> var Car = function () { this.speed = 'slow' };
  undefined
> Car.prototype = {color: 'white'};
  Object {color: "white"}
> var tesla = new Car();
  undefined
> tesla
  Car {speed: "slow", color: "white"}
> tesla.prototype
  undefined
> tesla.hasOwnProperty('color');
  false
> tesla.hasOwnProperty('speed');
  true

Notice how tesla.prototype does not exist. When tesla is created as a Car object, it's properties are augmented by the properties in Car.prototype. Looking closer, we also see that the JavaScript runtime in the Chrome browser 'cheats' by telling us that color is a property of the variable tesla. Using the hasOwnProperty function1 however, we see that color is actually a property of tesla's prototype. Shown below is the same example using the Object.create function2, as it was done during class.

> var car = {'color': 'white'};
  undefined
> car
  Object {color: "white"}
> var tesla = Object.create(car);
  undefined
> tesla.speed = 'slow';
  "slow"
> tesla.prototype
  undefined
> tesla.hasOwnProperty('color');
  false
> tesla.hasOwnProperty('speed');
  true
 

Object.create creates a new object, sets its prototype to the passed in argument, and then returns that object. So in order to actually create the same object as we did in the previous example any variables set in the prototype there would actually have to be set in the car object here. Note that instead of setting the speed of tesla to slow after creation, it can be supplied in the call to Object.create.

As we're learning JavaScript, some good reference material would be Douglas Crockford's book 'JavasScript; The Good Parts', as well as his posted videos on the yuiblog site.


Tutorial 3 Overview

For this tutorial and any consecutive tutorials the node_modules folder will be provided with the demo code. Otherwise, modules can be downloaded/installed using the node package manager (npm command) which is installed with node.

The tutorial consists of a demo application which simulates a basic login process, complete with cookie-based sessions. The basic flow is as follows: when a user logs in the server will set some cookies via the response which is sent back to the browser. Once this occurs the cookies will be sent with every request & response until they expire. For most cookies this is either when the browser closes, or when a certain length of time has passed. Dealing with these cookies is done by middleware which is set in the app.js file, as shown below.

25 app.use(express.cookieParser('COMP2406 rules!'));
26 app.use(express.session());

For our purposes, all interaction is done with the request's session object (req.session) during routing. An example of this is shown in index.js, where we test the session object for a username. If the username exists then we know that we have previously logged the user in, so we render the page. Otherwise, we redirect them to the home page. When viewing this process from the developer console in either Firefox or Chrome (or another browser), we'll see http status codes associated with the requests; either a 200 OK or a 302 Moved Temporarily.

13 function users(req, res) {
14     if (req.session.username) {
15         res.render("account.jade", {username:req.session.username,
16             title:"Account",
17             loggedInUsers: loggedInUsers});
18     } else {
19         res.redirect("/?error=Not Logged In");
20     }
21 };

Not only the status codes are shown in the developer's console. Also shown is more information about any requests; header information (including the user agent string), form/query parameters, cookies, and the actual content of responses.

The above code snippet also shows us something about Jade. Put simply, it's a template engine; it takes template code and transforms it into html. What's even more impressive is that we can pass variables to the templates which will be inserted onto the pages when this transformation occurs. This is shown on line 15 by the call to res.render where we pass in the template file followed by an object of variables.

One last thing which should be also be mentioned is session hijacking. Consider the situation that we have, where login information is stored in the cookies. If an adversary was able to guess how our cookies were constructed, then they would be able to fake being a user, and would gain access to the user's account. To help protect against this the express session module employs cryptographic hashing in order to obfuscate cookies. This type of hashing can't be reversed, so validity is checked through a re-hashing of supplied data which is compared to an existing hash.


Miscellaneous

How do we start node?
Different linux distributions may call the package different names. The two most common are node, and nodejs.
What's the difference between the prototype property and the object's prototype.
An object's prototype property is just that, a property named prototype. When that object is used as the base class for another object however, the new object will have the hidden [[Prototype]] property set as the base classes .prototype property. See this StackOverflow answer for more information.
What's the deal with equality predicates? Which ones should I be using?
Whenever you're able to, use a === b instead of a == b, etc. The double equals is able to carry out type coercion, which may be an unintended side effect. In addition to this, there are other small differences in equality checking.
Is there another way to set the object prototype?
There are a few ways, which are all listed on this page in the Mozilla Developer Network Javascript Guide!
The Comp 2406 virtual machine isn't running well on my machine!
Well, check out the video lectures starting with this one; if the VM is running slower than the one in class then odds are that your computer is misconfigured.