# Session Documentation

A session is a fundamental part of any authentication system. At a high level, a session is a way to remember that a user has logged in to your application.
Sessions are typically created when a user logs in and are used to validate the user on subsequent requests.

PropelAuth BYO’s Sessions feature starts out simple but allows you to easily add more advanced features as your application grows, like:

- Alerting users for logins on new devices
- Limiting concurrent sessions
- Tying a session to the user’s device to prevent session/cookie theft
- Giving your users visibility into their active sessions - allowing them to do remote logouts for lost devices
- Enabling individual customers to set an IP allowlist for their office’s IP address

Let’s look at how to get started with Sessions and some of the configuration options available.

## Basic Usage

The three key functions are [Create Session](https://docs.byo.propelauth.com/sessions/reference#create-session), [Validate Session](https://docs.byo.propelauth.com/sessions/reference#validate-session), and [Invalidate Session](https://docs.byo.propelauth.com/sessions/reference#invalidate-session-by-token).
In your backend, you can use the [Create Session](https://docs.byo.propelauth.com/sessions/reference#create-session) function to create a session and store the session token in an HTTP cookie for us to use later on:

**Node**
```javascript
app.post("/api/login", async (req, res) => {
    const user = validateCredentials(req);
    const result = await client.session.create({
        userId: user.userId,
        ipAddress: req.ip,
        userAgent: req.headers["user-agent"],
    });
    if (!result.ok) {
        console.error("Error creating session:", result.error);
        return res.status(500).json({ error: "Internal server error" });
    }
    setCookie(res, "sessionToken", result.data.sessionToken);
    res.json({ success: true });
});
```

**Python**
```python
@app.post("/api/login")
async def login(request: Request, response: Response):
    user = validate_credentials(request)
    result = await client.session.create(
        user_id=user.user_id,
        ip_address=request.client.host,
        user_agent=request.headers.get("user-agent"),
    )
    if is_err(result):
        print("Error creating session:", result.error)
        raise HTTPException(status_code=500, detail="Internal server error")
    set_cookie(response, "sessionToken", result.data.session_token)
    return {"success": True}
```

You can read the session token from the cookie and use the [Validate Session](https://docs.byo.propelauth.com/sessions/reference#validate-session) function to check if the session is still valid:

**Node**
```javascript
app.get("/api/user/whoami", async (req, res) => {
    const sessionToken = req.cookies.sessionToken;
    const result = await client.session.validate({
        sessionToken: sessionToken,
        ipAddress: req.ip,
        userAgent: req.headers["user-agent"],
    });
    if (result.ok) {
        res.json({ userId: result.data.userId });
    } else {
        res.status(401).json({ error: "Unauthorized" });
    }
});
```

You can invalidate the user’s session when they log out:

**Node**
```javascript
app.post("/api/logout", async (req, res) => {
    const sessionToken = req.cookies.sessionToken;
    await client.session.invalidateByToken({ sessionToken });
    deleteCookie(res, "sessionToken");
    res.json({ success: true });
});
```

## Configuring Session Settings

PropelAuth sessions come with a variety of defaults such as length and number of concurrent sessions permitted. These defaults can be configured in the `session_config.jsonc` configuration file. See [here](https://docs.byo.propelauth.com/sessions/reference#configuring-session-settings) for a full reference of all the configuration options.

```json
{
    "defaults": {
        "absolute_lifetime_secs": 1209600,
        "inactivity_timeout_secs": 3600,
        "max_concurrent_sessions_per_user": 8,
        "on_session_limit_exceeded": "drop_oldest",
        "disallow_ip_address_changes": true,
        "ip_allowlist": ["10.0.0.1/32"],
        "ip_blocklist": ["12.34.56.78/32"]
    }
}
```

## Session Tags

Each session can have 0 or more tags to customize settings like shorter session lengths for specific customers. For instance:

```json
{
    "tags": [
        {
            "tag": "customer:their_id",
            "absolute_lifetime_secs": 43200
        }
    ]
}
```

## Using the User Agent Property

You can include a `userAgent` property when creating and validating sessions, which helps in detecting suspicious user agent changes.

## Session Audit Logs

Structured logs emit JSON for easy ingestion into your logging system.

## Fetching a user’s active sessions

You can give users visibility into their active sessions using the [Fetch All For User](https://docs.byo.propelauth.com/sessions/reference#fetch-all-for-user) function:

```javascript
const result = await client.session.fetchAllForUser({ userId: user.userId });
if (result.ok) {
    res.json(result.data.sessions);
} else {
    res.status(500).json({ error: "Internal server error" });
}
```

Each session includes helpful information like the device’s user agent, IP address, and last activity time.

## Using Stateless Tokens (JWTs)

Stateless Tokens (JWTs) can validate sessions without network requests, suitable for high scale applications.

## Device Registration

Registering devices enhances security by providing proof requests come from the registered device.

## Putting it all together

Sessions in PropelAuth BYO are designed to grow with your application.
