# `PhoenixKit.Utils.SessionFingerprint`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/phoenix_kit/utils/session_fingerprint.ex#L1)

Session fingerprinting utilities for preventing session hijacking.

This module provides functions to create and verify session fingerprints based on
IP address and user agent data. These fingerprints help detect when a session token
is being used from a different location or device than where it was created.

## Security Considerations

- IP addresses can change (mobile users, VPNs, etc.), so strict enforcement may
  impact legitimate users
- User agents can be spoofed, but provide an additional layer of verification
- This is defense-in-depth: fingerprinting complements, not replaces, other security measures

## Configuration

You can configure the strictness level in your application config:

    config :phoenix_kit,
      session_fingerprint_enabled: true,
      session_fingerprint_strict: false  # true = force re-auth, false = log warnings

## Examples

    # Create a fingerprint from a connection
    fingerprint = SessionFingerprint.create_fingerprint(conn)

    # Verify a fingerprint
    case SessionFingerprint.verify_fingerprint(conn, stored_ip, stored_ua_hash) do
      :ok -> # Fingerprint matches
      {:warning, :ip_mismatch} -> # IP changed, but might be legitimate
      {:warning, :user_agent_mismatch} -> # User agent changed
      {:error, :fingerprint_mismatch} -> # Both changed, likely hijacked
    end

# `t`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/phoenix_kit/utils/session_fingerprint.ex#L46)

```elixir
@type t() :: %PhoenixKit.Utils.SessionFingerprint{
  ip_address: String.t(),
  user_agent_hash: String.t()
}
```

# `create_fingerprint`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/phoenix_kit/utils/session_fingerprint.ex#L62)

Creates a session fingerprint from a Plug.Conn connection.

Returns a `%SessionFingerprint{}` struct with `:ip_address` and `:user_agent_hash` fields.

## Examples

    iex> create_fingerprint(conn)
    %SessionFingerprint{ip_address: "192.168.1.1", user_agent_hash: "a1b2c3d4..."}

# `fingerprinting_enabled?`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/phoenix_kit/utils/session_fingerprint.ex#L200)

Checks if session fingerprinting is enabled in the application config.

## Examples

    iex> fingerprinting_enabled?()
    true

# `get_ip_address`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/phoenix_kit/utils/session_fingerprint.ex#L81)

Extracts the IP address from a connection.

Handles proxied connections by checking X-Forwarded-For and X-Real-IP headers,
falling back to the direct connection IP.

## Examples

    iex> get_ip_address(conn)
    "192.168.1.1"

# `hash_user_agent`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/phoenix_kit/utils/session_fingerprint.ex#L118)

Extracts and hashes the user agent from a connection.

Returns a SHA256 hash of the user agent string for privacy and storage efficiency.

## Examples

    iex> hash_user_agent(conn)
    "a1b2c3d4e5f6..."

# `strict_mode?`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/phoenix_kit/utils/session_fingerprint.ex#L216)

Checks if strict fingerprint verification is enabled.

When strict mode is enabled, fingerprint mismatches will force re-authentication.
When disabled, mismatches only log warnings.

## Examples

    iex> strict_mode?()
    false

# `verify_fingerprint`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/phoenix_kit/utils/session_fingerprint.ex#L144)

Verifies a session fingerprint against the current connection.

Returns:
- `:ok` if fingerprint matches
- `{:warning, :ip_mismatch}` if only IP changed
- `{:warning, :user_agent_mismatch}` if only user agent changed
- `{:error, :fingerprint_mismatch}` if both changed
- `:ok` if stored fingerprint is nil (backward compatibility)

## Examples

    iex> verify_fingerprint(conn, "192.168.1.1", "abc123")
    :ok

    iex> verify_fingerprint(conn, "10.0.0.1", "abc123")
    {:warning, :ip_mismatch}

---

*Consult [api-reference.md](api-reference.md) for complete listing*
