`

Living Without Sessions

 
阅读更多

When we talk about sessions in Web app development, we're usually talking about server stored data about a particular client. Some Web frameworks use session state to track and hold information about the user throughout their journey through the site, however they go against the RESTful principles and should really be treated as a bug.

Developers became used to having sessions available to them, so when systems grew, became more complex, and started spreading over multiple servers, more and more hacks had to be introduced to keep the session support working, when in reality, sessions should never have been introduced in the first place.

This article isn't to argue the pros and cons of server sessions, you can research that for yourself on the Web, we're going to look at an example system that is commonly built using sessions and how we can avoid sessions and come up with a better system.

Building a shopping cart with sessions

We're going to look at a standard shopping cart application, it will do the usual, display a bunch of products to the client and allow them to place them into their cart.

With sessions, we'd create a session, tie it to the client, and use it to store the IDs of each product the user places in their basket. Great, until we get a gazillion users and our server burns up in a firey memory related hell or we try to load balance across multiple servers so we need to buy expensive load balancers with layer 7 sticky session support. Yuk! There must be a better way, well infact there isn't a better way, there are two.

Cart on the client

When you think about someone in real life going into a shop and placing items into their shopping basket, where is the basket? It's with the user. So why don't we model our online shop to mirror the real life scenario.

Web browsers used to be a document reader for displaying hypertext documents transfered over the HTTP protocol, but nowerdays they are an application platform thanks to the development and deployment of Javascript within the HTML document and the browser. So we can use Javascript to extend our clients browser to be able to store their shopping cart until they reach the checkout.

We have to do a little work to make the browser hold it's state between page requests. We have a few choices:

  • Place the catelogue part of the site in a frameset with a "basket" frame that stores and displays the users basket to them. Pretty easy to do but not great since frames are a usability nightmare and we have to do extra work to provide bookmarkable URLs to individual products.
  • Expect the client to also support cookies and stuff the cart data in there. Very easy to do and they can persist for as long as we need, but cookies weren't designed for client state storage and they'll be sent to the server with every request when we only need them to be available to our client.
  • Wait until the WHATWG Web Application 1.0 spec is finished and implemented in browsers and use the new sessionStorage object.

Cart on the server

On the server, isn't that the same as storing a session on the server?

Yes and no. We can store the users cart on the server as long as we do it in a RESTful way we won't hit any of the problems associated with user sessions. The problem with sessions is that we're storing client state on the server, however if we don't treat the clients cart as being part of their state and rather treat it as being part of the shop itself, then we can get around the problems with sessions.

Imagine a shop where rather than being self-service, there is a shopkeeper who upon being asked, goes and fetches the items you want and rings them up on the till. Now if we were to model that as our online shop we'd see that the client no longer has a basket as part of their state, the basket is part of the shop.

So how would this work? Looking at the interactions between the client and the server, it might look something like this:

Client Server Client Server Client Server Client Server Client Server
Show me your products.
Here's a list of all the products you can buy at this shop.
Good, okay, I'd like to buy 1 of http://example.org/shop/product/X, please place it in my basket, my username is "JohnDoe" and my password is "secretPassword".
Okay, I've added 1 of http://example.org/shop/product/X into your basket, you can review your basket at http://example.org/shop/users/johndoe/basket
I'd like to buy 1 of http://example.org/shop/product/Y as well, please place one in my basket, my username is "JohnDoe" and my password is "secretPassword".
Okay, I've added 1 of http://example.org/shop/product/Y into your basket as well, you can still review your basket at http://example.org/shop/users/johndoe/basket
Actually I don't want http://example.org/shop/product/X after all, please remove it from my cart, my username is "JohnDoe" and my password is "secretPassword".
Okay, I've removed http://example.org/shop/product/X from your basket, you can review your updated basket at http://example.org/shop/users/johndoe/basket
Okay I'm done, ring 'em up, my username is "JohnDoe" and my password is "secretPassword".
Should I charge that to your expense account?

The thing to notice about this conversation is that it is stateless, every action from the client is independent of any other. This means that at any time, the user can run off and do something else, come back a few days later and carry on. It also means they could get some other service to add things to their shopping basket easily.

Ain't that just a session?

So how does this differ from storing the cart in a user session on the server? After all doesn't the conversation above also apply no matter whether we're storing the cart in a session or in a resource?

Firstly a users session is transitory, it's there when the user is there, but will be cleaned up and lost once they leave, in our RESTful design the cart is as integral as a user account, so whatever means we use to store and process user accounts we use to store and process the users cart (so it might be a MySQL database cluster with Memcached in front of it).

Secondly we can grab hold of the users cart since it's a resource that has a URL, so we can query and manipulate it at will, pass the URL to other services, etc.

The differences can seem very subtle, but it's the subtleties that make the difference, since we're explicitly creating and adjusting resources on the server all the problems of session handling disappear and are covered by our resource handling solution (our DB cluster for example).

Conclusion

Avoiding sessions is a bit of a purest stance, but it does lead to a more scalable and usable Web app. Keeping the clients state on the client is always a good idea, you can't scale better than by utilising someone elses computer, of course depending on your application and the technologies you are using your mileage may vary.

If you do find you need to store transitory client data on the server, think about re-working that data or the way your app. works so that the data has meaning, give it a URL and turn it into a resource the user can manipulate.

[转自:http://www.peej.co.uk/articles/no-sessions.html]

分享到:
评论

相关推荐

    Paypal Sessions Viewer--for zencart1.5

    【Paypal Sessions Viewer--for zencart1.5】是一个专为Zen Cart 1.5电子商务平台设计的工具,主要用于查看Paypal交易过程中的会话数据。这个工具可以帮助店主更好地理解Paypal支付流程中用户的交互行为,从而进行...

    virtual-art-sessions, "Virtual Art Sessions" Chrome 实验的源.zip

    virtual-art-sessions, "Virtual Art Sessions" Chrome 实验的源 虚拟艺术课程这个库镜像了活动的虚拟艺术会话站点( 代码 NAME 项目 Udon ),并已经打开了Apache许可 2.0,让任何感兴趣的人都可以发现它,看看它是...

    Go-Sessions用于http服务器的简单高性能高度可定制的用户会话

    Sessions 用于http服务器的简单,高性能,高度可定制的用户会话

    i-Sessions - MetaTrader 5脚本.zip

    在MT5中,“i-Sessions”是一款特别设计的脚本,用于显示和分析全球不同市场的交易会话,这对于全球交易者理解市场动态至关重要。 交易会话是指金融市场在特定时间段内的活跃交易时段。主要的交易会话包括亚洲、...

    django-redis-sessions, 在Redis数据库中,用于存储会话的Django 会话后端.zip

    django-redis-sessions, 在Redis数据库中,用于存储会话的Django 会话后端 django-redis-sessions用于你的会话的Redis数据库后端 安装工具可用设置变更日志文件安装运行 pip install django-redis-sessions 或者另外...

    How to kill terminal server sessions

    Utilities for terminal services: qwinsta and rwinsta

    红鸟Sessions类 v1.0

    红鸟Sessions类,用mysql数据库接管原来由文件系统支撑的php session,解决了session兼容性、虚拟主机无法自定义session等问题,内置gc函数,可以按概率触发删除过期session。...hn_sessions.sql:数据库sql文件;

    log-sessions-2021-08-21-041328.session

    log-sessions-2021-08-21-041328.session

    MobaXterm_20.5官方版.zip_sessions99个

    在MobaXterm_20.5官方版中,"sessions99个"可能是指该版本包含了99个预定义或已保存的会话配置。这些会话可能是用户经常访问的不同服务器或网络设备的配置,每个会话都保存了特定的连接参数,如主机名、端口、用户名...

    开源项目-adam-hanna-sessions.zip

    "adam-hanna-sessions" 的设计理念是使这一过程变得简单,避免复杂的配置,并确保在高负载下仍能保持高效运行。 【标签】"开源项目":这个标签表明"adam-hanna-sessions"是一个开放源代码的项目,意味着它的源代码...

    在Web Services中管理Sessions

    在Web服务中管理Session是构建可扩展且状态感知的应用程序的关键技术。Web服务通常是无状态的,这意味着每个请求都是独立的,不保留任何上下文信息。然而,有时我们需要跟踪用户会话,例如在购物车应用或个性化服务...

    paypal_sessions_viewer_3-02incl-pushorder

    【标题】"paypal_sessions_viewer_3-02incl-pushorder" 指的是一款名为 PayPal Session Viewer 的软件工具,版本号为 3.02,其中包含了 "pushorder" 功能。这款工具主要针对电子商务平台,尤其是使用 Zen Cart 框架...

    前端开源库-client-sessions

    "client-sessions"是一个专门针对前端应用的开源库,它旨在提供一种安全且高效的方式来存储和管理用户会话,全部在客户端进行,无需服务器端参与。这个库特别适合那些不希望频繁与服务器交互或需要离线支持的应用...

    sessions:用于会话管理的Gin中间件

    会话 用于会话管理的Gin中间件,具有多后端支持:用法开始使用它下载并安装: $ go get github.com/gin-contrib/sessions 将其导入您的代码中: import "github.com/gin-contrib/sessions"基本范例单节package main...

    hibernate_org - Sessions and transactions

    hibernate_org - Sessions and transactions

    gin-sessions:Gin 的会话中间件

    store := sessions . NewCookieStore ([] byte ( "secret123" )) g . Use ( sessions . Middleware ( "my_session" , store )) g . GET ( "/set" , func ( c * gin. Context ){ session := sessions . Get ( c

    使用 Redis 的 gorilla,sessions 会话存储后端 .zip

    使用 Redis 的 gorilla/sessions 会话存储后端。重新恢复 gorilla/sessions的会话存储后端- src。要求依赖于Redigo Redis 库。安装go get gopkg.in/boj/redistore.v1文档可在godoc.org上获取。有关底层接口的完整...

    PHP实例开发源码-红鸟Sessions类 v1.0.zip

    1. 安全性:红鸟Sessions类可能会对Session ID进行加密处理,防止Session hijacking(会话劫持)攻击,确保用户数据的安全。 2. 自定义存储:该类允许开发者自定义Session数据的存储方式,可以是文件系统、数据库或...

    dreamweaver中php设置“Sessions"插件

    dreamweaver中php设置“Sessions"插件

Global site tag (gtag.js) - Google Analytics