Server Side Sessions -------------------- By default, Flask will store user session information in a client-side cookie. This works, however, it has some drawbacks. For instance, it doesn't allow sessions to be terminated by the server, implementation and user details get exposed in the cookie, and logout isn't fully implemented (Flask asks the browser to delete the cookie, and it will, but if the cookie had been saved/intercepted and later resubmitted, eg by a nefarious party, the cookie would continue to work even though the user thought they logged out). Using server side sessions solves these problems for us, and it's really easy to set up thanks to `Flask-Session `_. Install Dependencies ^^^^^^^^^^^^^^^^^^^^ .. code:: bash pip install "flask-unchained[session]" Enable the Session Bundle: .. code:: python # unchained_config.py BUNDLES = [ # ... 'flask_unchained.bundles.session', 'app', ] Configuration ^^^^^^^^^^^^^ Let's configure the Session Bundle to use SQLAlchemy: .. code:: python # app/config.py class Config(BundleConfig): # ... SESSION_TYPE = 'sqlalchemy' SESSION_SQLALCHEMY_TABLE = 'flask_sessions' Because the Session Bundle is just a thin wrapper around Flask Session, configuration options are the same as documented in `the official docs `_. Database Migrations ^^^^^^^^^^^^^^^^^^^ And now we need to create the table, using a database migration: .. code:: bash flask db migrate -m 'create sessions table' It's always a good idea to inspect the migration to make sure it's going to do exactly what you expect it to do before running it. It should look something about like this: .. code:: python # db/migrations/versions/[hash]_create_sessions_table.py """create sessions table Revision ID: 17c5247038a6 Revises: Create Date: 2018-07-30 11:50:19.709960 """ from alembic import op import sqlalchemy as sa import flask_unchained.bundles.sqlalchemy.sqla.types as sqla_bundle # revision identifiers, used by Alembic. revision = '17c5247038a6' down_revision = None branch_labels = None depends_on = None def upgrade(): # ### commands auto generated by Alembic - please adjust! ### op.create_table('flask_sessions', sa.Column('id', sa.Integer(), nullable=False), sa.Column('session_id', sa.String(length=255), nullable=False), sa.Column('data', sa.LargeBinary(), nullable=False), sa.Column('expiry', sa.DateTime(), nullable=True), sa.Column('created_at', sqla_bundle.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False), sa.Column('updated_at', sqla_bundle.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False), sa.PrimaryKeyConstraint('id', name=op.f('pk_flask_sessions')), sa.UniqueConstraint('session_id', name=op.f('uq_flask_sessions_session_id')) ) # ### end Alembic commands ### def downgrade(): # ### commands auto generated by Alembic - please adjust! ### op.drop_table('flask_sessions') # ### end Alembic commands ### Once you're satisfied, run the migration: .. code:: bash flask db upgrade That's it for setting up server side sessions! Let's make a commit before we continue: .. code:: bash git add . git status git commit -m 'install session bundle' And proceed to :doc:`security` using the Security Bundle.