Main  /  Edit version 5  /  Edit version 6  /   /  Users Area

Difference "Sessions" ver. 5 versus ver. 6

Content:

<!--toc-->
## General
In this tutoring we would show the basics of using sessions in CppCMS --- how to store connection persistent data in stateless HTTP protocol.
## Code
Our current code would be based on [start with forms](/wikipp/en/page/cppcms_1x_forms) code.
### Templates and Content
In this example we would save the information about user using `session_interface` object that can be accessed by `session()` member function of `cppcms::application`.
This information would be displayed to the user every time one visits the page.
First of all let's change our "content.h": Instead of showing person's sex and state we should display a prefix "Mr", "Miss" or "Mrs" according to our saved parameters.
So lets change line:
std::string name,state,sex;
to
std::string name,who;
And we would use following template:
<h1>Hello <%= who %> <%= name %></h1>
<% if (content.age != -1.0) %>
<p>Your age is <%= age %></p>
<h2>Change details</h2>
<% else %>
<h2>Input your details</h2>
<% end %>
<form method="post" action="" >
<% form as_p info %>
__Notes:__ We can inject arbitrary C++ code into conditions between two brackets `()` (line 2). However, now we should refer to all content class variables using `content` member. Templates engine would not substitute correct prefix for you, because it is native C++ code.
### Saving data
Now let's rewrite out `hello::main` function:
First of all let's load new data from the form when it submitted to session object, instead of content. This information is preserved withing different requests:
content::message c;
if(request().request_method()=="POST") {
c.info.load(context());
if(c.info.validate()) {
session()["name"]=c.info.name.value();
session()["sex"]=c.info.sex.selected_id();
session()["state"]=c.info.martial.selected_id();
session().set("age",c.info.age.value());
c.info.clear();
}
}
__Notes:__
- Note on operator `[]` of session object:
string &session_interface::operator[](string const &)
It's semantics similar to semantics of `std::map`'s `[]` operator. Accessing it's member returns the reference to the string by the key. If key not exists, it is created.
- The storage object is std::string. In order to store other different values, you should do lexical cast to string. The simplest way is to use template member function
template<typename T>
void set(string const &key,T const &value);
Now, our session data would be preserved between requests and we can fetch it:
### Fetching Data
if(session().is_set("name")) {
c.name=session()["name"];
if(session()["sex"]=="m") {
c.who="Mr";
}
else {
if(session()["state"]=="s") {
c.who="Miss";
}
else {
c.who="Mrs";
}
}
c.age=session().get<double>("age");
}
else {
c.name="Visitor";
c.age=-1;
}
render("message",c);
__Notes:__
- First time, you ask for any field, you should check if it is exists:
if(session().is_set("name")) {
It would be incorrect to write:
if(!session()["name"].empty()) {
Because you would change session object and set the
value of "name" to empty string, and this value would
be saved. This is probably not what you want.
Then, if you always set all fields together, it is safe
to fetch them directly. CppCMS sessions guarantees
consistency of the data.
- You can fetch non-string values using template member function:
template<typename T>
T get(std::string const &key)
- `get` and `set` template member functions use C++ `std::istream` and `std::ostream` to convert the data between the textual representation and its value.
So you can use any type T that is writable to and readable
from C++ I/O streams.
## Configuration --- behind the scenes
### Storage Backend
CppCMS has several options to session management. In every case cookies are used --- there is no "GET" or "POST" methods for storing session information like `/page/?sid=2e7f60c43b88d4b554a`.
The developer has several options to save information:
- Store all data at client side in signed and optionally encrypted cookies
- Store all data at server size and use session id to retrieve the information each time
- Store all data at server side and use session id to retrieve the information each time
- Use combination of them: If amount of data too big to be
stored in cookies, it would be stored on server side.
We would add following lines to our CppCMS configuration file:
"session" : {
"expire" : "renew",
"timeout" : 604800,
"location" : "client",
"client" : {
"hmac" : "sha1",
"hmac_key" : "3891bbf7f845fd4277008a63d72640fc13bb9a31"
}
}
__Notes:__
- Defining `session.location`, would enable session interface. Most suitable option for 99% of cases is to store the data in signed and encrypted cookies on client side.
- When using client side storage the signature method (hmac) and a suitable private key should be provided.
Optionally an encryption can be added by setting
`session.client.cbc` method like aes and providing
a private key.
You should keep the private key unique per application and never disclose it. You may generate such key easily using `cppcms_make_key` utility that uses [`/dev/random`](http://en.wikipedia.org/wiki/Urandom) interface.
### Duration Options
You can define several session duration options:
- Browser based, until window is closed --- "browser" -- the default one.
- Time based with renewal --- "renew"
- Time based with hard limit after first time creation --- "fixed". It is useful when you want to force user to login every predefined period of time.
Each type of expiration has its time limit (even browser one has its limit). It can be defined using `session.timeout` parameter. The default one is 24 hours.
For example:
"expire" : "renew",
"timeout" : 604800,
## Security Considerations
The full tutorial about sessions and security can
be found here:
- [Secure Programming: Sessions](/wikipp/en/page/secure_programming#Sessions)
Make sure you read it and understand it.
Rules of thumb:
- Don't store valuable data in the session, it is ok to store user identification or preferences but it is not
good idea to store user's rights.
- If you use client side storage be aware of replay-attacks - where user can restore his cookie to previous state.
- Call `session().reset_session()` after critical operations like authentication in order to prevent session-fixation attacks.
---
← [Working With Forms][prev]
| [Top](#maincontent)
| [Basic Caching][next] →
[prev]: /wikipp/en/page/cppcms_1x_forms
[next]: /wikipp/en/page/cppcms_1x_basic_caching

About

CppCMS is a web development framework for performance demanding applications.

Support This Project

SourceForge.net Logo

Поддержать проект

CppCMS needs You


Navigation

Main Page


Valid CSS | Valid XHTML 1.0