Skip to content

Commit

Permalink
Make signing salt optional for Rails 3.2 compatibility.
Browse files Browse the repository at this point in the history
  • Loading branch information
hisea committed Feb 6, 2017
1 parent 78549a8 commit ec24ef4
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 4 deletions.
12 changes: 12 additions & 0 deletions README.md
Expand Up @@ -48,6 +48,7 @@ plug Plug.Session,
key: "_SOMETHING_HERE_session",
domain: '.myapp.com',
secure: true,
signing_with_salt: true,
signing_salt: "signing salt",
encrypt: true,
encryption_salt: "encryption salt",
Expand Down Expand Up @@ -106,6 +107,17 @@ Plug & Rails must use the same strategy for serializing cookie data.
serializer: RailsMarshalSessionSerializer
end
```

- __Rails 3.2__: Rails 3.2 uses unsalted signing, to make Phoenix share session with Rails 3.2 project you need to set up `ExMarshal` mentioned above, with following configuration in your `Plug.Session`:

```elixir
plug Plug.Session,
store: PlugRailsCookieSessionStore,
# ... see encryption/ExMarshal config above
signing_with_salt: false,
end
```


#### That's it!

Expand Down
13 changes: 9 additions & 4 deletions lib/plug_rails_cookie_session_store.ex
Expand Up @@ -128,9 +128,12 @@ defmodule PlugRailsCookieSessionStore do
defp derive(conn, key, key_opts) do
conn.secret_key_base
|> validate_secret_key_base()
|> KeyGenerator.generate(key, key_opts)
|> generate_key(key, key_opts)
end

defp generate_key(secret, nil, _), do: secret
defp generate_key(secret, key, key_opts), do: KeyGenerator.generate(secret, key, key_opts)

defp validate_secret_key_base(nil), do:
raise(ArgumentError, "cookie store expects conn.secret_key_base to be set")
defp validate_secret_key_base(secret_key_base) when byte_size(secret_key_base) < 64, do:
Expand All @@ -139,9 +142,11 @@ defmodule PlugRailsCookieSessionStore do
secret_key_base

defp check_signing_salt(opts) do
case opts[:signing_salt] do
nil -> raise ArgumentError, "cookie store expects :signing_salt as option"
salt -> salt
if Keyword.get(opts, :signing_with_salt, true) do
case opts[:signing_salt] do
nil -> raise ArgumentError, "cookie store expects :signing_salt as option"
salt -> salt
end
end
end

Expand Down
9 changes: 9 additions & 0 deletions test/plug_rails_cookie_session_store_test.exs
Expand Up @@ -13,6 +13,7 @@ defmodule PlugRailsCookieSessionStoreTest do

@secret String.duplicate("abcdef0123456789", 8)
@signing_opts Plug.Session.init(Keyword.put(@default_opts, :encrypt, false))
@signing_without_salt_opts Plug.Session.init(Keyword.put(@default_opts, :signing_with_salt, false))
@encrypted_opts Plug.Session.init(@default_opts)

defmodule CustomSerializer do
Expand Down Expand Up @@ -108,6 +109,14 @@ defmodule PlugRailsCookieSessionStoreTest do
assert CookieStore.get(conn, cookie, @signing_opts.store_config) == {nil, %{foo: :bar}}
end

test "session cookies are signed without salt" do
conn = %{secret_key_base: @secret}
cookie = CookieStore.put(conn, nil, %{foo: :bar}, @signing_without_salt_opts.store_config)
assert is_binary(cookie)
assert CookieStore.get(conn, cookie, @signing_without_salt_opts.store_config) == {nil, %{foo: :bar}}
end


test "gets and sets signed session cookie" do
conn = conn(:get, "/")
|> sign_conn()
Expand Down

0 comments on commit ec24ef4

Please sign in to comment.