# Sessions

Channels supports standard Django sessions using HTTP cookies for both HTTP and WebSocket. There are some caveats, however.

## Basic Usage

The `SessionMiddleware` in Channels supports standard Django sessions, and like all middleware, should be wrapped around the ASGI application that needs the session information in its scope (for example, a `URLRouter` to apply it to a whole collection of consumers, or an individual consumer).

`SessionMiddleware` requires `CookieMiddleware` to function. For convenience, these are also provided as a combined callable called `SessionMiddlewareStack` that includes both. All are importable from `channels.session`.

To use the middleware, wrap it around the appropriate level of consumer in your `asgi.py`:

    from channels.routing import ProtocolTypeRouter, URLRouter
    from channels.security.websocket import AllowedHostsOriginValidator
    from channels.sessions import SessionMiddlewareStack

    from myapp import consumers

    application = ProtocolTypeRouter({

        "websocket": AllowedHostsOriginValidator(
            SessionMiddlewareStack(
                URLRouter([
                    path("frontend/", consumers.AsyncChatConsumer.as_asgi()),
                ])
            )
        ),

    })

`SessionMiddleware` will only work on protocols that provide HTTP headers in their `scope` - by default, this is HTTP and WebSocket.

To access the session, use `self.scope["session"]` in your consumer code:

    class ChatConsumer(WebsocketConsumer):

        def connect(self, event):
            self.scope["session"]["seed"] = random.randint(1, 1000)

`SessionMiddleware` respects all the same Django settings as the default Django session framework, like `SESSION_COOKIE_NAME` and `SESSION_COOKIE_DOMAIN`.

## Session Persistence

Within HTTP consumers or ASGI applications, session persistence works as you would expect from Django HTTP views - sessions are saved whenever you send a HTTP response that does not have status code `500`.

This is done by overriding any `http.response.start` messages to inject cookie headers into the response as you send it out. If you have set the `SESSION_SAVE_EVERY_REQUEST` setting to `True`, it will save the session and send the cookie on every response, otherwise it will only save whenever the session is modified.

If you are in a WebSocket consumer, however, the session is populated but will never be saved automatically - you must call `scope["session"].save()` yourself whenever you want to persist a session to your session store. If you don’t save, the session will still work correctly inside the consumer (as it’s stored as an instance variable), but other connections or HTTP views won’t be able to see the changes.

Note

If you are in a long-polling HTTP consumer, you might want to save changes to the session before you send a response. If you want to do this, call `scope["session"].save()`.