Ferreteria/sql/user session

From Woozle Writes Code
< Ferreteria‎ | sql
Revision as of 00:53, 27 January 2017 by htyp>Woozle (Woozle moved page VbzCart/tables/user session to Ferreteria/sql/user session: okay, *this* is the final table to move to Ferreteria)
Jump to navigation Jump to search

About

This table was originally an inextricable part of VbzCart, but it is now mostly handled through the standalone user-session library. Only ID_Cart and ID_Order have been added for VbzCart.

  • Rules: A new session should be created whenever the "same" client doesn't remember the session cookie (could be a different computer on the same IP address), or if the session has timed out.
  • Relations:
    • Each Template:Vbzcart has one or more Template:Vbzcarts
    • Each Template:Vbzcart has zero or one Template:Vbzcarts
      • A single session may discard one cart and start a new one.
      • Sessions only use carts they create, never reusing one created by another session (but see Security, below)
      • Each session knows only the cart it is currently using.
  • Usage:
    • For now, we will be treating each Template:Vbzcart as having its own session which never expires. Having a separate class for the session, though, lets us decouple these things later on if we want to.
    • There should eventually be an "empty cart" button; if the user has not logged in, then that button should start a new session rather than clearing the cart for the current session.

Fields

  • Stash: a place to put serialized application data (maybe there should be a convention about prefixing key-names with the app's name)
  • WhenClosed: if not NULL, then this session should not be reused. If this session is accessed after the time of WhenExpires, code should manually set WhenClosed to NOW().

Future

The ID_Cart and ID_Order fields should probably be stored in Stash instead of having dedicated fields. Then this table could be used by other apps without alteration.

Security

I briefly toyed with the idea of only allowing the session to be set via http query within the secure area once and thereafter requiring it to come from a cookie, but anyone familiar with wget could spoof a cookie pretty easily, so this didn't seem worth the effort.

The real security comes from requiring that client's fingerprint (browser + IP address) "match" those in the session record for the session token (which the client must also give) before authorizing renewal of a session for that client. The session token is essentially a "shared secret" generated by the server.

However, once a user has created a login, it seems reasonable to allow them to reuse sessions where the browser ID or IP address (or at least to retain their login). Tentatively, this should be a user option that is off (more secure) by default.

History

  • 2009-06-18 design started - first draft, not sure concept is right
  • 2009-07-10 each session ties to a cart, not vice-versa; Token is now a random string
  • 2011-02-07 fixing bug where user gets the same cart again after placing an order:
    • ID_Cart is now cleared when cart is converted to an order, so that same cart won't get reloaded
    • ID_Order field so we can still pull up the order when ID_Cart is cleared
    • Remember, this is the active cart. After cart is converted to an order, it is no longer active.
  • 2011-03-27 decided that clearing ID_Cart is a bad idea, because:
    • user can't reload the receipt page
    • we can't detect if the user has already sent in an order, so we can't ask if they want to add to it or modify it
  • 2013-09-26 added ID_User -- this is how we know if the user is logged in.
  • 2013-11-09
    • renamed from shop_session to user_session
    • moved ID_User above ID_Cart, since that and ID_Order are now "additions" to the base class as defined in user-session.php
  • 2016-12-23 added Stash BLOB field for storing arbitrary session values (messages, display preferences, maybe eventually Cart ID)

SQL

<mysql>CREATE TABLE `user_session` (

 `ID`        INT     NOT NULL AUTO_INCREMENT,
 `ID_Client` INT     NOT NULL COMMENT "user_client.ID",
 `ID_User`   INT DEFAULT NULL COMMENT "ID of logged-in user, if any",
 `ID_Cart`   INT DEFAULT NULL COMMENT "shop_cart.ID currently active for this session",
 `ID_Order`  INT DEFAULT NULL COMMENT "order ID to which cart was converted (if any)",
 `Token`     VARCHAR(31)      COMMENT "session identifier passed as cookie = random string",
 `Stash`    BLOB DEFAULT NULL COMMENT "other values associated with the session (PHP serialized)",
 `WhenCreated` DATETIME       COMMENT "when session was created",
 `WhenExpires` DATETIME       COMMENT "when session was due to expire",
 `WhenClosed`  DATETIME       COMMENT "when the session was closed",
 PRIMARY KEY(`ID`),
 UNIQUE KEY(`Token`)
) ENGINE = MYISAM;</mysql>