Flask: An Intro to using Session in server-client communication
Published: 2023-08-08 16:08:55

###What is Session?
A session is a means for storing information related to a user, across different requests, as they interact with a web app.  In Flask, we import session from Flask, which is a data object, and this session object works similar to a dictionary, except that it can also keep track of modifications.

There are two types of sessions commonly used in web development, client-side and sever-side.  Client-side are stored client-side in browser cookies, and server-side sessions are stored server-side; however, a session identifier is typically then created and stored in browser cookies. 

Some benefits to using sessions are speed and ability to scale; however, sessions are limited in their size (cookies typically no more than 4kb),and session data is cryptographically-signed upon being stored as cookies, but they are not encrypted. As a result, sessions should not be used to store sensitive information like passwords or personal information.

Session is a great way to keep a user logged into your site through refreshes or over time.  Sessions can also be used to keep track of lists or items if you are say shopping and grabbing multiple items from different page loads.

###Implementation in your Flask App
Implementing session in your flask application is not very difficult; however, there are a number of ways to add additional functionality and control how your server application utilizes session.  For configuration, the first step is to import session from Flask.
```
from flask import session
```  Then, you simply need to call on the session object within any functions that needs to access the session data.  Typically, this can be done in the same manner that we would access information in a dictionary.  One of the most common uses of session for flask applications is to check whether current session data exists. 
```
@app.route('/')
def index():
   if 'username' in session:
      username = session['username']
```
This can be done to help direct what pages a browser has access to based on whether a current session exists.  Another common application of session involves logging in a user or creating a new user.
```
@app.route('/login', methods = ['GET', 'POST'])
def login():
   if request.method == 'POST':
      session['username'] = request.form['username']
```
This session is called upon during the POST method and updates or sets a key in the session object to the data received from the POST request.  Another important aspect is being able to delete session data, which typically occurs upon a user logging out.  This can be done a few different ways, but the important points to remember is that the to remove the values for the session keys that need to be deleted.
```
sesssion['username'] = None #example A
session.pop('username', None) #example B
```
Lastly, let's touch on updating the session data.  Most of the time, the session object is capable of automatically tracking and accounting for changes to the session.  However, modifications to mutable data structures such as lists are not accounted for automatically, and instead must be accounted for by setting the modified attribute of session `session.modified = True` to True.  A common occurence of this would be when storing a bunch of items in a cart say for online shopping. 
```
cart_item = {'pencil': '10', 'eraser': '5', 'marker': '20'}
if 'cart_item' in session:
    session['cart_item']['marker'] = '35'
    session.modified = True
```

###Session and the secret key
An important part of session is that there is some data being provided and stored on the client-side that represents information which we do not want the client to be able to modify.  Therefore, a secret key is used to cryptographically-sign the cookies used for storing the session data.  We do this to ensure if the client tries to manipulate data within the session ID, we want it to be rejected by the server.  In other words, anyone has the permission to view the contents in the cookie but they can’t modify it unless they have the secret key .  Therefore, as best practice one wants to create a random somewhat complicated key, and there are a number of options for generating a secure random key.  One common way is to use your operating system, which has ways has ways to generate pretty random stuff based on a random cryptographic generator.  
```
$ python -c 'import os; print(os.urandom(16))'
b'\r6CZO\x03\xdd<\x8c\x1f\xf4\xf44\x15\xe5\xd6'
```
The code implemented merely sets the `.secret_key` property of app using a method `.urandom` that will generate a random byte string the size of the argument.  This randomly generated key can then be stored in your app, should be set during setup or even as part of the configuration as shown below.
```
app.secret_key = b'\r6CZO\x03\xdd<\x8c\x1f\xf4\xf44\x15\xe5\xd6' #Ex.A
app.config['SECRET_KEY']= b'\r6CZO\x03\xdd<\x8c\x1f\xf4\xf44\x15\xe5\xd6' #Ex. B
```

###Conclusion
The session object is essentially a dictionary for storing relevant information about a current user from the client-side in order to maintain knowledge about that user over the length of the connection and that includes multiple requests between the client and server. They are important because they allow the application to maintain state across multiple requests, without needing authentication information from the user with each request. This helps to build better applications that are interactive and responsive to user input.