google app engine sessions and cookies
DESCRIPTION
Google App Engine Sessions and Cookies. ae-09-session. www.appenginelearn.com. Cookies and Sessions Maintaining State in HTTP. High Level Summary. The web is “stateless” The browser does not maintain a connection to the server while you are looking at a page. - PowerPoint PPT PresentationTRANSCRIPT
Google App Engine Sessions and Cookies
ae-09-session
www.appenginelearn.com
Cookies and SessionsMaintaining State in HTTP
High Level Summary
•The web is “stateless”
•The browser does not maintain a connection to the server while you are looking at a page.
•You may never come back to the same server
•Or it may be a long time
•Or it may be one second later
High Level Summary
•The web is “stateless”
•So we need a way for servers to know “which browser is this?”
•In the browser, state is stored in “Cookies”
•In the server, state is stored in “Sessions”
Some Web sites always seem to want to know who you are!
Other Web sites always seem to know who you are!
Browser
Server
GET
WholePage
GET
WholePage
Draw Draw
You watch the YouTube videofor an 30 seconds
How you see YouTube...
ClickClick
Browser
Server
GET
WholePage
GET
WholePage
How YouTube sees you...
Draw DrawClickClick
Multi-User•When a server is interacting with many different
browsers at the same time, the server needs to know *which* browser a particular request came from
•Request / Response initially was stateless
•All browsers looked identical
•This was was fine for static web pages
•But it was really really bad for "webapps"
• Those simple days did not last very long at all.
Web Cookies to the Rescue
http://en.wikipedia.org/wiki/HTTP_cookie
Technically, cookies are arbitrary pieces of data chosen by the Web server and sent to the
browser. The browser returns them unchanged to the server, introducing a state (memory of
previous events) into otherwise stateless HTTP transactions. Without cookies, each retrieval of a
Web page or component of a Web page is an isolated event, mostly unrelated to all other
views of the pages of the same site.
http://en.wikipedia.org/wiki/HTTP_cookie
Cookies In the Browser•Cookies contain markers indicating the web
addresses they come from
•The browser only sends a cookie to the web server that originally set it
•Cookies have an expiration date
•Some last for years
•Others are short-term and go away as soon as the browser is closed
Playing with Cookies
•Firefox's WebDeveloper plugin has a set of cookie features
•Other browsers have a way to view or change cookies
Cookies
•Identifying individual users across requests
•Making the web seem not to be stateless
Request / Response Again!
HTTP Request / Response Cycle
http://www.oreilly.com/openbook/cgi/ch04_02.html
Browser
Web Server
HTTPRequest
HTTPResponse
Internet Explorer, FireFox, Safari,
etc.
(Review)
HTTP Request / Response Cycle
GET /index.html HTTP/1.1Accept: www/sourceAccept: text/htmlUser-Agent: Lynx/2.4
http://www.oreilly.com/openbook/cgi/ch04_02.html
Browser
Web Server
HTTPRequest
We do our initialGET to a server.
The server checks to see if
we have a cookie with a particular
name set.Since this is our first interaction,
we have no cookies set for
this host.
HTTP Request / Response Cycle
http://www.oreilly.com/openbook/cgi/ch04_02.html
Browser
Web Server
HTTPResponse
HTTP/1.1 200 OKContent-type: text/htmlSet-Cookie: sessid=123
<head> .. </head><body><h1>Welcome ....
host: sessid=123
Along with the rest of the
response, the server sets a
cookie with some name (sessid) and sends it
back along with the rest of the
response.
HTTP Request / Response Cycle
GET /index.html HTTP/1.1Accept: www/sourceAccept: text/htmlCookie: sessid=123User-Agent: Lynx/2.4
http://www.oreilly.com/openbook/cgi/ch04_02.html
Browser
Web Server
HTTPRequest
host: sessid=123
From that point forward, each
time we send a GET or POST to the server, we
include any cookies which
were set by that host.
HTTP Request / Response Cycle
http://www.oreilly.com/openbook/cgi/ch04_02.html
Browser
Web Server
HTTPResponse
HTTP/1.1 200 OKContent-type: text/htmlSet-Cookie: name=chuck
<head> .. </head><body><h1>Welcome ....
host: sessid=123host:name=chuck
On each response, the
server can change a cookie
value. Or add another cookie.
HTTP Request / Response Cycle
GET /index.html HTTP/1.1Accept: www/sourceAccept: text/htmlCookie: sessid=123,name=ChuckUser-Agent: Lynx/2.4
http://www.oreilly.com/openbook/cgi/ch04_02.html
Browser
Web Server
HTTPRequest
From that point forward, each
time we send a GET or POST to the server, we include all the cookies which
were set by that host.host: sessid=123
host:name=chuck
Security
•We ony send cookies back to the host that originally set the cookie
•The browser has *lots* of cookies for lots of hosts
•To see all Cookies:
Firefox -> Preferences -> Privacy -> Show Cookies
The Firefox Web Developer Plugin Shows
Cookies for the Current Host.
Two Kinds of Cookies
•Long-lived - who you are - account name - last access time
•You can close and reopen your browser and it is still there
•Temporary - used to identify your session
•It goes away when you close the browser
Using Cookies to Support Sessions and Login /
Logout
Some Web sites always seem to want to know who you are!
In The Server - Sessions
•In most server applications, as soon as we meet a new browser we create a session
•We set a session cookie to be stored in the browser which indicates the session id in use
•The creation and destruction of sessions is generally handled by a web framework or some utility code that we just use to manage the sessions
Session Identifier•A large, random number that we place in a browser
cookie the first time we encounter a browser.
•This number is used to pick from the many sessions that the server has active at any one time.
•Server software stores data in the session which it wants to have from one request to another from the same browser.
•Shopping cart or login information is stored in the session in the server
ServerServer
Session 97Session 97
Browser CBrowser C
cook=97cook=97
Request
Response
index:index:
““PleasePleaselog in”log in”cook=97
CreateSession
ServerServer
Session 97Session 97
Browser CBrowser C
cook=97cook=97
Typing
We now have a session
establishedbut are not yet
logged in.
Login / Logout•Having a session is not the same as being logged in.
•Generally you have a session the instant you connect to a web site
•The Session ID cookie is set when the first page is delivered
•Login puts user information in the session (stored in the server)
•Logout removes user information from the session
ServerServer
Session 97Session 97
Browser CBrowser C
cook=97cook=97
Request
login:login:
if good:if good:set userset user
Click
cook=97cook=97
ServerServer
Session 97Session 97
user=philuser=phil
Browser CBrowser C
cook=97cook=97
Request
login:login:
if good:if good:set userset user
Click
Response
cook=97cook=97
ServerServer
Session 97Session 97
user=philuser=phil
Browser CBrowser C
cook=97cook=97
Using Sessions for Other Stuff
ServerServerBrowser ABrowser A
cook=10cook=10
Browser BBrowser B
cook=46cook=46
Session 10Session 10
user=chucuser=chuckk
bal=$100bal=$10000
Session 46Session 46
user=januser=janbal=$400bal=$400
ServerServer
Session 10Session 10
user=chucuser=chuckk
bal=$100bal=$10000
Session 46Session 46
user=januser=janbal=$500bal=$500
Browser ABrowser A
cook=10cook=10
Browser BBrowser B
cook=46cook=46
withdraw:withdraw:
bal=bal-bal=bal-100100
ServerServer
Session 10Session 10
user=chucuser=chuckk
bal=$100bal=$10000
Session 46Session 46
user=januser=janbal=$500bal=$500
Browser ABrowser A
cook=10cook=10
Browser BBrowser B
cook=46cook=46
withdraw:withdraw:
bal=bal-bal=bal-100100
Click
ServerServer
Session 10Session 10
user=chucuser=chuckk
bal=$100bal=$10000
Session 46Session 46
user=januser=janbal=$500bal=$500
Browser ABrowser A
cook=10cook=10
Browser BBrowser B
cook=46cook=46
cook=46cook=46
withdraw:withdraw:
bal=bal-bal=bal-100100
ServerServer
Session 10Session 10
user=chucuser=chuckk
bal=$100bal=$10000
Session 46Session 46
user=januser=janbal=$400bal=$400
Browser ABrowser A
cook=10cook=10
Browser BBrowser B
cook=46cook=46
cook=46cook=46
withdraw:withdraw:
bal=bal-bal=bal-100100
Response
Request
Review...
High Level Summary
•The web is “stateless” - the browser does not maintain a connection to the server while you are looking at a page. Yu may never come back to the same server - or it may be a long time - or it may be one second later
•So we need a way for servers to know “which browser is this?”
•In the browser state is stored in “Cookies”
•In the server state is stored in “Sessions”
Browser
Server
GET
WholePage
GET
WholePage
Draw Draw
You watch the YouTube videofor an 30 seconds
How you see YouTube...
ClickClick
Browser
Server
Draw DrawClickClick
GET
WholePage
GET
WholePage
Browser
Server
Draw DrawClickClick
GET
WholePage
GET
WholePage
Session 42Session 42
cook=
42
cook=
42
cook=
42
cook=
42
Session 42Session 42
Cookie/Session Summary•Cookies take the stateless web and allow servers to store
small “breadcrumbs” in each browser.
•Session IDs are large random numbers stored in a cookie and used to maintain a session on the server for each of the browsers connecting to the server
•Server software stores sessions *somewhere* - each time a request comes back in, the right session is retrieved based on the cookie
•Server uses the session as a scratch space for little things
Programming and Sessions
First Look: Sessions are Magic!
•Sessions are usually part of the built-in web application framework
•Ruby on Rails
•Java Web Applications
•PHP
•The framework does all the cookie setting and data finding
First Look: Sessions are Magic!
•In our controller code we simply ask to create and/or access a session
•We treat the session like a dictionary storing whatever we like in the session under a set of string keys that we choose
Session Rules•Keep them small - we don’t want to put too much in
the session or we start taxing memory and other storage resources and slowing down our application
•Focus on data that is used on nearly every incoming request - the lookup key of the current user - the email address of the current user
•Sessions generally go away when the user closes their browser (cookie is lost) or after a period of inactivity (1-3 hours)
Session Uses
•Indication of the current user - management of the login and log out process
•Shopping cart - items / quantities
Our Magic - sessions.py•Since the Google Application Engine does
not provide a session capability, we need to add one - extending our application
•Download from
http://www.appenginelearn.com/downloads/util.zip
•Install in your application in the directory util to make it available in your application
Using the Session
from util.sessions import Session
class LogoutHandler(webapp.RequestHandler): def get(self): self.session = Session() self.session.delete('username') doRender(self, 'index.htm')
The Session() call either establishes a session or accesses the current session.
Inside the Session() call
•We use a session cookie to look up our session
•If the cookie exists and the session exists, return that session
•If not pick a large random number as the session key, make a session and set a temporary cookie with the session key as its value
The Login/Logout Pattern
•We use a key named ‘username’ in the session to indicate that the user is logged in
•If the key is missing the user is logged out
•If the key is present, its value is the account of the logged in user (e.g. “csev”)
def post(self): self.session = Session() acct = self.request.get('account') pw = self.request.get('password') logging.info("Checking account="+acct+" pw="+pw)
self.session.delete('username')
if pw == "" or acct == "": doRender(self,"login.htm",{'error' : 'Please specify Acct/PW'} ) elif pw == "secret": self.session['username'] = acct doRender(self,"index.htm",{ } ) else: doRender(self,"login.htm",{'error' : 'Incorrect password'} )
Get the Session
Log out previous user
Log in new user
Logout
from util.sessions import Session
class LogoutHandler(webapp.RequestHandler): def get(self): self.session = Session() self.session.delete('username') doRender(self, 'index.htm')
Get the Session
Log out previous user
Navigation
•We want to have the Login / Logout button flip when we log in or out and we want to see the name of the current logged in user.
<li><a href="topics.htm" {% ifequal path '/topics.htm' %} class="selected" {% endifequal %} >Topics</a></li> {% ifequal username None %} <li><a href="/login" {% ifequal path '/login' %} class="selected" {% endifequal %} >Login</a></li> {% else %} <li><a href="/logout">Logout ({{username}})</a></li> {% endifequal %}
In the view template, we send an additional
context variable to the template called
“username” if the user is logged in. We use logic in
the template to either generate the Login link or
the Logout + account name link.
_base.htm
def doRender(self, tname = "index.htm", values = { }): logging.info(tname) temp = os.path.join(os.path.dirname(__file__),'templates/'+tname) if not os.path.exists(temp): return False
# Make a copy of the dictionary and add basic values newval = dict(values) if not 'path' in newval: path = self.request.path newval['path'] = self.request.path
if not 'username' in newval: self.session = Session() if 'username' in self.session: newval['username'] = self.session["username"]
outstr = template.render(temp, newval) self.response.out.write(outstr) return True
We check to see if the username is in the
session and if username is in the
session we add it to the context variables to be
passed into the template.
Summary
•The Cookies and Session work together to give us a relatively simply way to programmatically stash data associated with a particular user/browser
•While the mechanisms are a bit complex, the session pattern turns out to be pretty simple to use in our applications
•The Google Application Engine does not provide us with a Session feature - so we need to write or borrow some code
•Clever use of session is important to application performance