Skip to content


Session Middleware is supported on web requests and responses in the form of signed-cookies/headers and server-side data storage. When configured, the middleware will check for a session-cookie/header on the request; if a cookie/header is not found on the request, or the session is not in storage, then a new session is created and attached to the response. If there is a session, then the appropriate data for that session is loaded from storage.

The duration of the session-cookie/header can be specified, as well as whether to extend the duration each time on each request. A secret-key to sign sessions can be supplied (default is a random GUID), as well as the ability to specify custom data stores - the default is in-memory, but custom storage could be anything like Redis/MongoDB/etc.


Using sessions via headers is best used with REST APIs and the CLI. It's not advised to use them for normal websites, as browsers don't send back response headers in new requests - unlike cookies.


To initialise sessions in Pode use Enable-PodeSessionMiddleware. This function will configure and automatically create the Middleware needed to enable sessions. By default sessions are set to use cookies, but support is also available for headers.

Sessions are automatically signed using a random GUID. For Pode running on a single server using the default in-memory storage this is OK, however if you're running Pode on multiple servers, or if you're defining a custom storage then a -Secret is required - this is so that sessions from different servers, or after a server restart, don't become corrupt and unusable.


The following is an example of how to setup session middleware using cookies. Each session created will expire after 2mins, but the expiry time will be extended each time the session is used:

Start-PodeServer {
    Enable-PodeSessionMiddleware -Duration 120 -Extend

The default name of the session cookie is pode.sid, but this can be customised using the -Name parameter.


Sessions are also supported using headers - useful for CLI requests. The following example will enable sessions use headers instead of cookies:

Start-PodeServer {
    Enable-PodeSessionMiddleware -Duration 120 -Extend -UseHeaders

When using headers, the default name of the session header in the request/response is pode.sid - this can be customised using the -Name parameter. When you make an initial request to authenticate some user, the pode.sid header will be returned in the response. You can then use the value of this header in subsequent requests for the authenticated user, and then make a call using the session one last time against some route to expire the session - or just let it automatically expire.


The inbuilt SessionId generator used for sessions is a GUID, but you can supply a custom generator using the -Generator parameter.

If supplied, the -Generator is a scriptblock that must return a valid string. The string itself should be a random unique value, that can be used as a unique session identifier.

Within a route, or middleware, you can get the current authenticated sessionId using Get-PodeSessionId. If there is no session, or the session is not authenticated, then $null is returned. This function can also returned the fully signed sessionId as well. If you want the sessionId even if it's not authenticated, then you can supply -Force to get the sessionId back.


You can flag sessions as being strict using the -Strict switch. Strict sessions will extend the signing process by also using the client's UserAgent and RemoteIPAddress, to help prevent session sharing on different browsers/consoles.

Pode will automatically extend the Secret for signing for you, whether you're using the default GUID, or supplying a specific -Secret value.


The inbuilt storage for sessions is a simple in-memory store - with auto-cleanup for expired sessions.

You can define a custom storage by supplying a psobject to the -Storage parameter, and also note that a -Secret will be required. The psobject supplied should have the following NoteProperty scriptblock members:

[hashtable] Get([string] $sessionId)
[void]      Set([string] $sessionId, [hashtable] $data, [datetime] $expiry)
[void]      Delete([string] $sessionId)

For example, the following is a mock up of a Storage for Redis (note that the functions are fake):

# create the object
$store = New-Object -TypeName psobject

# add a Get property for retreiving a session's data by SessionId
$store | Add-Member -MemberType NoteProperty -Name Get -Value {
    return (Get-RedisKey -Key $sessionId)

# add a Set property to save a session's data
$store | Add-Member -MemberType NoteProperty -Name Set -Value {
    param($sessionId, $data, $expiry)
    Set-RedisKey -Key $sessionId -Value $data -TimeToLive $expiry

# add a Delete property to delete a session's data by SessionId
$store | Add-Member -MemberType NoteProperty -Name Delete -Value {
    Remove-RedisKey -Key $sessionId

# enable session middleware - a secret is required
Enable-PodeSessionMiddleware -Duration 120 -Storage $store -Secret 'schwifty'

Session Data

To add data to a session you can utilise the .Session.Data property within the web event object accessible in a Route - or other Middleware. The data will be saved at the end of the route automatically using Endware. When a request is made using the same sessionId, the data is loaded from the store. For example, incrementing some view counter:

Add-PodeRoute -Method Get -Path '/' -ScriptBlock {

You can also use the $session: variable scope, which will get/set data on the current session for the name supplied. You can use $session: anywhere a $WebEvent is available - such as routes, middleware, authentication and endware. The same view counter example above:

Add-PodeRoute -Method Get -Path '/' -ScriptBlock {

$session: can only be used in the main scriptblocks of routes, etc. If you attempt to use it in a function of a custom module, it will fail; even if you're using the function in a route. Pode remaps $session: on server start, and can only do this to the main scriptblocks supplied to functions such as Add-PodeRoute.


An example of using sessions in a Route to increment a views counter could be done as follows (the counter will continue to increment on each call to the route until the session expires after 2mins):

Start-PodeServer {
    Add-PodeEndpoint -Address localhost -Port 8080 -Protocol Http
    Enable-PodeSessionMiddleware -Duration 120

    Add-PodeRoute -Method Get -Path '/' -ScriptBlock {
        Write-PodeJsonResponse -Value @{ 'Views' = $WebEvent.Session.Data.Views }
Back to top