|
defmodule SessionCookieInspector do |
|
@moduledoc """ |
|
Debug utility for decoding Phoenix session cookies. |
|
|
|
## Configuration |
|
|
|
Provide raw cookie, `signing_salt`, `secret_key_base` as function arguments. |
|
|
|
## Usage |
|
Runa.SessionInspector.inspect(cookie, signing_salt, secret_key_base) |
|
""" |
|
|
|
@doc """ |
|
Decodes the signed session cookie. |
|
|
|
Returns `{:ok, map}` on success or `{:error, reason}`. |
|
""" |
|
@spec decode(String.t(), String.t(), String.t()) :: |
|
{:ok, map()} | {:error, atom()} |
|
def decode(cookie, signing_salt, secret_key_base) when is_binary(cookie) do |
|
signing_key = |
|
Plug.Crypto.KeyGenerator.generate(secret_key_base, signing_salt) |
|
|
|
case String.split(cookie, ".", parts: 3) do |
|
[_, payload, signature] -> |
|
signed_value = "#{payload}--#{signature}" |
|
|
|
case Plug.Crypto.MessageVerifier.verify(signed_value, signing_key) do |
|
nil -> |
|
{:error, :invalid_signature} |
|
|
|
_unsigned -> |
|
with {:ok, raw} <- Base.url_decode64(payload, padding: false), |
|
term <- :erlang.binary_to_term(raw) do |
|
{:ok, term} |
|
else |
|
:error -> {:error, :invalid_base64} |
|
end |
|
end |
|
|
|
_ -> |
|
{:error, :invalid_cookie_format} |
|
end |
|
end |
|
|
|
@doc """ |
|
Decodes and prints the session data. |
|
""" |
|
@spec inspect(String.t(), String.t(), String.t()) :: :ok | {:error, atom()} |
|
def inspect(cookie, signing_salt, secret_key_base) when is_binary(cookie) do |
|
case decode(cookie, signing_salt, secret_key_base) do |
|
{:ok, data} -> |
|
data |
|
|
|
{:error, reason} -> |
|
IO.puts("Failed to decode session: #{reason}") |
|
{:error, reason} |
|
end |
|
end |
|
end |