Loading ...
Sorry, an error occurred while loading the content.
 

How to embed user specific content in a common page?

Expand Messages
  • Christian Helmbold
    Hello, lets say I have a web shop with a product page that contains a panel with the shopping cart. The product page should be the same for all users, but the
    Message 1 of 14 , Jun 16, 2010
      Hello,

      lets say I have a web shop with a product page that contains a panel with the shopping cart. The product page should be the same for all users, but the shopping cart should be individual for each user. But if the page is the same for all users, it cannot contain an individual URI for the user's shopping cart!

      My idea is to store the cart URI in a cookie and request the cart form the server with content of that cookie. The process looks like this:

      1. Client: GET /product
      2. Server: Ok, product page
      3. Client: POST /cart (requested with JavaScript)
      4. Server: Created, Location: /cart/93a41fe545b, set_cookie: /cart/93a41fe545b

      ... on the next page:

      5. Client: GET /another_product
      6. Server: Ok, another product page
      7. Client: GET /cart/93a41fe545b (requested with JavaScript after reading the cookie)
      8. Server: Ok, user's shopping cart

      Maybe the actual creation of the shopping cart can be deferred until the first item is placed into the cart, but that is not important for my example. Important is the mechanism to store the cart URI in a cookie and request and display the cart with JavaScript.

      Is there a way to do something similar without JavaScript?

      What do you think of this approach?


      Another idea:

      Since this kind of shopping cart could be shared between users (e. g. configure a computer for someone else and send the URI of the cart) it would make sense, to make shopping carts immutable. If the cart is modified, the user gets a new cart URI, so that all previous versions would still be available. The obvious shortcoming is that many carts will be stored over time ... But disk space is cheap and old, unused carts could be removed after a while. Any opinion?

      Regards
      Christian


      --
      http://scala-forum.org/
    • christian.helmbold
      Hello, lets say I have a web shop with a product page that contains a panel with the shopping cart. The product page should be the same for all users, but the
      Message 2 of 14 , Jun 16, 2010
        Hello,

        lets say I have a web shop with a product page that contains a panel with the shopping cart. The product page should be the same for all users, but the shopping cart should be individual for each user. But if the page is the same for all users, it cannot contain an individual URI for the user's shopping cart!

        My idea is to store the cart URI in a cookie and request the cart form the server with content of that cookie. The process looks like this:

        1. Client: GET /product
        2. Server: Ok, product page
        3. Client: POST /cart (requested with JavaScript)
        4. Server: Created, Location: /cart/93a41fe545b, set_cookie: /cart/93a41fe545b

        ... on the next page:

        5. Client: GET /another_product
        6. Server: Ok, another product page
        7. Client: GET /cart/93a41fe545b (requested with JavaScript after reading the cookie)
        8. Server: Ok, user's shopping cart

        Maybe the actual creation of the shopping cart can be deferred until the first item is placed into the cart, but that is not important for my example. Important is the mechanism to store the cart URI in a cookie and request and display the cart with JavaScript.

        Is there a way to do something similar without JavaScript?

        What do you think of this approach?


        Another idea:

        Since this kind of shopping cart could be shared between users (e. g. configure a computer for someone else and send the URI of the cart) it would make sense, to make shopping carts immutable. If the cart is modified, the user gets a new cart URI, so that all previous versions would still be available. The obvious shortcoming is that many carts will be stored over time ... But disk space is cheap and old, unused carts could be removed after a while. Any opinion?

        Regards
        Christian
      • Alan Dean
        It s not exactly what you asked, but here is a series of blog posts from 2008 where I discuss my opinion on baskets ( carts in american english):
        Message 3 of 14 , Jun 16, 2010
          It's not exactly what you asked, but here is a series of blog posts from 2008 where I discuss my opinion on baskets ('carts' in american english):


          Regards,
          Alan Dean

          On Wed, Jun 16, 2010 at 19:05, Christian Helmbold <christian.helmbold@...> wrote:
           

          Hello,

          lets say I have a web shop with a product page that contains a panel with the shopping cart. The product page should be the same for all users, but the shopping cart should be individual for each user. But if the page is the same for all users, it cannot contain an individual URI for the user's shopping cart!

          My idea is to store the cart URI in a cookie and request the cart form the server with content of that cookie. The process looks like this:

          1. Client: GET /product
          2. Server: Ok, product page
          3. Client: POST /cart (requested with JavaScript)
          4. Server: Created, Location: /cart/93a41fe545b, set_cookie: /cart/93a41fe545b

          ... on the next page:

          5. Client: GET /another_product
          6. Server: Ok, another product page
          7. Client: GET /cart/93a41fe545b (requested with JavaScript after reading the cookie)
          8. Server: Ok, user's shopping cart

          Maybe the actual creation of the shopping cart can be deferred until the first item is placed into the cart, but that is not important for my example. Important is the mechanism to store the cart URI in a cookie and request and display the cart with JavaScript.

          Is there a way to do something similar without JavaScript?

          What do you think of this approach?

          Another idea:

          Since this kind of shopping cart could be shared between users (e. g. configure a computer for someone else and send the URI of the cart) it would make sense, to make shopping carts immutable. If the cart is modified, the user gets a new cart URI, so that all previous versions would still be available. The obvious shortcoming is that many carts will be stored over time ... But disk space is cheap and old, unused carts could be removed after a while. Any opinion?

          Regards
          Christian

          --
          http://scala-forum.org/


        • Jan Algermissen
          ... Why do you want the page to be the same for all users? Caching? Here is what you could do: Link to /cart from the product page and redirect /cart to
          Message 4 of 14 , Jun 16, 2010
            On Jun 16, 2010, at 8:05 PM, Christian Helmbold wrote:

            > Hello,
            >
            > lets say I have a web shop with a product page that contains a panel with the shopping cart. The product page should be the same for all users, but the shopping cart should be individual for each user. But if the page is the same for all users, it cannot contain an individual URI for the user's shopping cart!

            Why do you want the page to be the same for all users? Caching?

            Here is what you could do:

            Link to /cart from the product page and redirect /cart to /cart/tom for user Tom based on Authorization header.


            GET /cart
            Authorization: Thomas Magnum

            307 Temporary Redirect
            Location: /cart/tom



            Even better: use client side storage (even if it is cookie-based) to store user state (the cart).

            Jan




            >
            > My idea is to store the cart URI in a cookie and request the cart form the server with content of that cookie. The process looks like this:
            >
            > 1. Client: GET /product
            > 2. Server: Ok, product page
            > 3. Client: POST /cart (requested with JavaScript)
            > 4. Server: Created, Location: /cart/93a41fe545b, set_cookie: /cart/93a41fe545b
            >
            > ... on the next page:
            >
            > 5. Client: GET /another_product
            > 6. Server: Ok, another product page
            > 7. Client: GET /cart/93a41fe545b (requested with JavaScript after reading the cookie)
            > 8. Server: Ok, user's shopping cart
            >
            > Maybe the actual creation of the shopping cart can be deferred until the first item is placed into the cart, but that is not important for my example. Important is the mechanism to store the cart URI in a cookie and request and display the cart with JavaScript.
            >
            > Is there a way to do something similar without JavaScript?
            >
            > What do you think of this approach?
            >
            >
            > Another idea:
            >
            > Since this kind of shopping cart could be shared between users (e. g. configure a computer for someone else and send the URI of the cart) it would make sense, to make shopping carts immutable. If the cart is modified, the user gets a new cart URI, so that all previous versions would still be available. The obvious shortcoming is that many carts will be stored over time ... But disk space is cheap and old, unused carts could be removed after a while. Any opinion?
            >
            > Regards
            > Christian
            >
            >
            > --
            > http://scala-forum.org/
            >
            >
            >
            >
            >
            > ------------------------------------
            >
            > Yahoo! Groups Links
            >
            >
            >

            -----------------------------------
            Jan Algermissen, Consultant
            NORD Software Consulting

            Mail: algermissen@...
            Blog: http://www.nordsc.com/blog/
            Work: http://www.nordsc.com/
            -----------------------------------
          • Christian Helmbold
            ... Yes, I had caching in mind. ... Temporary Redirect ... A user is not necessarily authenticated. ... Ok, that would be an opportunity. Christian
            Message 5 of 14 , Jun 16, 2010
              > Why do you want the page to be the same for all
              > users? Caching?

              Yes, I had caching in mind.

              > Here is what you could do:

              > Link to /cart from the
              > product page and redirect /cart to /cart/tom for user Tom based on Authorization
              > header.
              >
              > GET /cart
              > Authorization: Thomas Magnum
              >
              > 307
              >
              Temporary Redirect
              > Location: /cart/tom

              A user is not necessarily authenticated.

              > Even better: use client
              > side storage (even if it is cookie-based) to store user state (the
              > cart).

              Ok, that would be an opportunity.

              Christian
            • Craig McClanahan
              On Wed, Jun 16, 2010 at 10:18 PM, Christian Helmbold
              Message 6 of 14 , Jun 17, 2010
                On Wed, Jun 16, 2010 at 10:18 PM, Christian Helmbold <christian.helmbold@...> wrote:
                 



                > Why do you want the page to be the same for all
                > users? Caching?

                Yes, I had caching in mind.


                > Here is what you could do:

                > Link to /cart from the
                > product page and redirect /cart to /cart/tom for user Tom based on Authorization
                > header.
                >
                > GET /cart
                > Authorization: Thomas Magnum
                >
                > 307
                >
                Temporary Redirect
                > Location: /cart/tom

                A user is not necessarily authenticated.

                This seems like a good opportunity to make up a random cart identifier for the unauthenticated user.  In fact, you should make up a random cart identifier for authenticated users too.  That way, you're removing an attack vector from a malicious hacker that figures out your "/cart/{username}" URI pattern.  Plus, it makes it easy to maintain the stateless constraint even for authenticated users (the cart and its associated ID expires after some timeout period).
                 
                So, for either authenticated or unauthenticated users, send them to "/cart/{cartID}" where cartID is a randomly calculated value that has an expiration -- basically this is the same kind of thing that Java servlet containers do with session IDs, to reduce the chance that an attacker can guess an appropriate value.
                 
                Craig
                 

                > Even better: use client
                > side storage (even if it is cookie-based) to store user state (the
                > cart).

                Ok, that would be an opportunity.

                Christian


              • Mike Kelly
                On Wed, Jun 16, 2010 at 7:05 PM, Christian Helmbold ... That approach is pretty clean - clients are allowed to maintain their own state, it s driven by
                Message 7 of 14 , Jun 17, 2010
                  On Wed, Jun 16, 2010 at 7:05 PM, Christian Helmbold
                  <christian.helmbold@...> wrote:
                  > Hello,
                  >
                  > lets say I have a web shop with a product page that contains a panel with the shopping cart. The product page should be the same for all users, but the shopping cart should be individual for each user. But if the page is the same for all users, it cannot contain an individual URI for the user's shopping cart!
                  >
                  > My idea is to store the cart URI in a cookie and request the cart form the server with content of that cookie. The process looks like this:
                  >
                  > 1. Client: GET /product
                  > 2. Server: Ok, product page
                  > 3. Client: POST /cart (requested with JavaScript)
                  > 4. Server: Created, Location: /cart/93a41fe545b, set_cookie: /cart/93a41fe545b
                  >
                  > ... on the next page:
                  >
                  > 5. Client: GET /another_product
                  > 6. Server: Ok, another product page
                  > 7. Client: GET /cart/93a41fe545b (requested with JavaScript after reading the cookie)
                  > 8. Server: Ok, user's shopping cart
                  >
                  > Maybe the actual creation of the shopping cart can be deferred until the first item is placed into the cart, but that is not important for my example. Important is the mechanism to store the cart URI in a cookie and request and display the cart with JavaScript.
                  >
                  > Is there a way to do something similar without JavaScript?
                  >
                  > What do you think of this approach?

                  That approach is pretty clean - clients are allowed to maintain their
                  own state, it's driven by hypertext, and you're using code on demand
                  (because you have to).

                  I prefer an approach with a 3xx redirect as Jan described, you could
                  private cache the 3xx response and you end up with the same effect as
                  the cookie approach.

                  I wouldn't bother trying to 'store the cart on the client side' though
                  - you'll gain virtually nothing from it (apart from a headache and a
                  deep hatred for the browser 'platform') and more than likely still end
                  up storing the cart state to the server anyway.

                  Cheers,
                  Mike
                • Christian Helmbold
                  ... described, you could ... up ... How does that private caching work? The server doesn t know which cart to deliver when another product page asks the
                  Message 8 of 14 , Jun 17, 2010
                    > I prefer an approach with a 3xx redirect
                    > as Jan
                    described, you could
                    > private cache the 3xx response and you end
                    up
                    > with the same effect as
                    > the cookie approach.

                    How does that "private caching" work? The server doesn't know which cart to deliver when another product page asks the server for the users
                    cart, since the product page doesn't know the {cart-id}.

                    Christian
                    --
                    http://scala-forum.org/
                  • Christian Helmbold
                    ... I agree that a secure {cart-id} makes sense in any case. But the question, though, is where to store the {cart-id}? In a cookie? Embed it in the page that
                    Message 9 of 14 , Jun 17, 2010
                      > This seems like a good opportunity to make up a random cart identifier for the unauthenticated user. In fact, you should make up a random cart identifier for authenticated users too. That way, you're removing an attack vector from a malicious hacker that figures out your "/cart/{username}" URI pattern. Plus, it makes it easy to maintain the stateless constraint even for authenticated users (the cart and its associated ID expires after some timeout period).

                      I agree that a secure {cart-id} makes sense in any case. But the question, though, is where to store the {cart-id}? In a cookie? Embed it in the page that includes the cart and in all it's links? The latter would prevent caching and lead to personalized links like with session ids in the URIs.

                      Christian
                    • Mike Kelly
                      On Thu, Jun 17, 2010 at 10:28 AM, Christian Helmbold ... Each browser client can locally cache its unique redirect response from the /cart resource, which
                      Message 10 of 14 , Jun 17, 2010
                        On Thu, Jun 17, 2010 at 10:28 AM, Christian Helmbold
                        <christian.helmbold@...> wrote:
                        >
                        >> I prefer an approach with a 3xx redirect
                        >> as Jan
                        > described, you could
                        >> private cache the 3xx response and you end
                        > up
                        >> with the same effect as
                        >> the cookie approach.
                        >
                        > How does that "private caching" work? The server doesn't know which cart to deliver when another product page asks the server for the users
                        > cart, since the product page doesn't know the {cart-id}.
                        >


                        Each browser client can locally cache its 'unique' redirect response
                        from the /cart resource, which means that all pages can contain a
                        generic link e.g. <link rel="cart" href="/cart" /> , which renders the
                        pages themselves cacheable.

                        Each client can redirect to its actual cart without having to hit the
                        network since it can just take the redirect from its local cache.

                        Cheers,
                        Mike
                      • Mike Kelly
                        ... There appears to be a bug in chrome as it won t cache a 307 response. It works ok in firefox, I haven t tried anything else yet. You may be better off just
                        Message 11 of 14 , Jun 17, 2010
                          On Thu, Jun 17, 2010 at 11:05 AM, Mike Kelly <mike@...> wrote:
                          > On Thu, Jun 17, 2010 at 10:28 AM, Christian Helmbold
                          > <christian.helmbold@...> wrote:
                          >>
                          >>> I prefer an approach with a 3xx redirect
                          >>> as Jan
                          >> described, you could
                          >>> private cache the 3xx response and you end
                          >> up
                          >>> with the same effect as
                          >>> the cookie approach.
                          >>
                          >> How does that "private caching" work? The server doesn't know which cart to deliver when another product page asks the server for the users
                          >> cart, since the product page doesn't know the {cart-id}.
                          >>
                          >
                          >
                          > Each browser client can locally cache its 'unique' redirect response
                          > from the /cart resource, which means that all pages can contain a
                          > generic link e.g. <link rel="cart" href="/cart" /> , which renders the
                          > pages themselves cacheable.
                          >
                          > Each client can redirect to its actual cart without having to hit the
                          > network since it can just take the redirect from its local cache.
                          >
                          > Cheers,
                          > Mike
                          >

                          There appears to be a bug in chrome as it won't cache a 307 response.
                          It works ok in firefox, I haven't tried anything else yet.

                          You may be better off just using cookies to store the URI as a path of
                          least resistance :)

                          Cheers,
                          Mike
                        • Eric J. Bowman
                          Related discussion here: http://tech.groups.yahoo.com/group/rest-discuss/message/14395 -Eric
                          Message 12 of 14 , Jun 17, 2010
                          • Eric J. Bowman
                            ... Content negotiation involves architecting around some nasty-tricksy tradeoffs. My solution is to use browser-resident XSLT to transclude personalized
                            Message 13 of 14 , Jun 17, 2010
                              >
                              > Related discussion here:
                              >

                              Content negotiation involves architecting around some nasty-tricksy
                              tradeoffs. My solution is to use browser-resident XSLT to transclude
                              personalized content from a resource implementing authentication-
                              based conneg redirection, using HTTP Digest authentication.

                              GET /A responds with an XHTML stub, which calls a static XSLT file.
                              That XSLT file transforms Atom content from /B into XHTML, and also
                              transforms an XML personalization file from /C . Resource /C does not
                              initiate challenge-response in absence of an Authentication: header, it
                              responds 200 OK with 'Cache-Control: public' and its anonymous-user
                              variant.

                              When the request has an Authentication: header, /C may use role- or
                              user-based logic to redirect to role- or user-based variants whose
                              Location: is inside a directory which does initiate challenge-response
                              when no Authentication: header is present. This redirect can also use
                              HTTPS to secure HTTP Basic authentication, but I use Digest and Cache-
                              Control: private.

                              Thus, /A may securely expose an individual user's password in its
                              rendered steady-state, despite the fact that /A is a public-cached
                              resource. The drawback is that must-revalidate is required on /C , but
                              the browser-resident XSLT architecture effectively mitigates this,
                              allowing /A to scale anarchically, despite personalized content.

                              -Eric
                            • Eric J. Bowman
                              Of course, there s nothing about my solution that requires XSLT; that s just my solution. The same architecture may be implemented using XHR in /A to
                              Message 14 of 14 , Jun 17, 2010
                                Of course, there's nothing about my solution that requires XSLT; that's
                                just "my" solution. The same architecture may be implemented using XHR
                                in /A to request JSON personalization data from /C .

                                -Eric
                              Your message has been successfully submitted and would be delivered to recipients shortly.