elixir-plug / plug

Compose web applications with functions
https://hex.pm/packages/plug
Other
2.87k stars 586 forks source link

** (ArgumentError) cannot fetch key from conn.cookies because they were not fetched #1017

Closed yordis closed 3 years ago

yordis commented 3 years ago

Hey there,

I tried to figure out what I suppose to do to fix this issue, but the more I google the more I create an infinite loop to the same links and I don't understand how to fix it.

I am working in Ueberauth (https://github.com/ueberauth/ueberauth/pull/136), add CSRF attack protection, but my test cases keeps failing:

 9) test simple callback phase (UeberauthTest)
     test/ueberauth_test.exs:16
     ** (ArgumentError) cannot fetch key "ueberauth.state_param" from conn.cookies because they were not fetched
     code: |> SpecRouter.call(@opts)
     stacktrace:
       (plug 1.11.0) lib/plug/conn/unfetched.ex:35: Plug.Conn.Unfetched.raise_unfetched/3
       (elixir 1.11.2) lib/access.ex:286: Access.get/3
       (ueberauth 0.6.3) lib/ueberauth/strategy.ex:339: Ueberauth.Strategy.state_param_matches?/1
       (ueberauth 0.6.3) lib/ueberauth/strategy.ex:331: Ueberauth.Strategy.maybe_run_handle_callback/3
       (ueberauth 0.6.3) test/support/spec_router.ex:1: Support.SpecRouter.plug_builder_call/2
       test/ueberauth_test.exs:20: (test)

I assume there is some plug or something but I am stock, and I need help at this point.

Thanks in advance,

Related to: https://github.com/ueberauth/ueberauth/pull/136

yordis commented 3 years ago

I found something

I added

@session_options [
    store: :cookie,
    key: "_hello_key",
    signing_salt: "CXlmrshG"
  ]

  plug(Plug.Session, @session_options)

Or manually

conn(:get, "/oauth/simple-provider/callback", id: "foo", code: "simple-code")
      |> Plug.Session.call(@session_options) # need this!
      |> Ueberauth.run_callback(
        "simple-provider",
        {Support.SimpleProvider, [token_prefix: "token-"]}
      )

And then I call Plug.Conn.fetch_session/1

defp get_state_cookie(conn) do
    conn
    |> Conn.fetch_session()
    |> Map.get(:cookies)
    |> Map.get(@state_param_cookie_name)
  end

Question from this

Do people suppose to call Plug.Conn.fetch_session/1 in their code in order to avoid such a problem?

yordis commented 3 years ago

I would like to figure out the documentation for this.

  1. What we should do in order to fix the issue
  2. Do library authors should call Plug.Conn..fetch_session/1 before they try to access the cookie when they are building custom Plugs (also vs Phoenix environments I guess)

@josevalim any help on the topic? I am not sure the valid answers to them other than my isolated experience

yordis commented 3 years ago

@josevalim 🚀 thank you so much!