Git Product home page Git Product logo

Comments (18)

scrogson avatar scrogson commented on September 23, 2024 1

Plug.Session.fetch_session/1 is called every time Plug.Session is invoked: https://github.com/elixir-lang/plug/blob/master/lib/plug/session.ex#L54.

If you call Plug.Conn.fetch_session/1 it will raise "cannot fetch session without a configured session plug" if you don't have the session plug in the stack. If you call Plug.Conn.get_session/1 it will raise "session not fetched, call fetch_session/1". Since Plug.Session already does what's needed, it seems like Plug.Conn.fetch_session/1 is redundant.

Thoughts?

from plug.

ericmj avatar ericmj commented on September 23, 2024

I don't know why the plug/2 macro fails but have you started the ETS table?

from plug.

nurugger07 avatar nurugger07 commented on September 23, 2024

I had left that out because it was throwing an argument error when added to start/2. I just added it outside the module and it doesn't blow up. But, I still have to do:

get "/" do
  opts = Plug.Session.init(store: :ets, key: "_my_app_session", secure: true, table: :session)
  conn = Plug.Session.call(conn, opts)
  conn = fetch_session(conn)
  conn = put_session(conn, :foo, "bar")
  foo = get_session(conn, :foo)
  send_resp(conn, 200, foo)
end

Plus I forgot to mention, once you add those lines you can remove plug/2 completely and everything works the same. It's very curious and because other plugs seem to be working, I was thinking the problem was something I'm doing wrong. Especially, because there were no other reports of issues.

from plug.

scrogson avatar scrogson commented on September 23, 2024

Johnny, sounds like you already tried this? https://github.com/elixir-lang/plug/blob/master/lib/plug/session/ets.ex#L17

from plug.

nurugger07 avatar nurugger07 commented on September 23, 2024

@scrogson Yeah, this is a really simple plug app that's why I'm a little confused. Do you have a working example of sessions?

from plug.

josevalim avatar josevalim commented on September 23, 2024

I had left that out because it was throwing an argument error when added to start/2. I just added it outside the module and it doesn't blow up.

This is the issue. A ETS table is owned by the its process. Given compilation and runtime are distinct in Elixir, the process that created the ETS table (which is the one that compiled your code) is long gone. You need to create a ETS table in your supervisor or as part of your supervision tree and make it public.

There are two things we need to do from this discussion:

  1. Improve the all session docs to use cookie store by default
  2. Improve the ETS specific docs to mention the semantics above

from plug.

nurugger07 avatar nurugger07 commented on September 23, 2024

@josevalim There also doesn't appear to be a need to add Plug.Session as a plug.

I don't mind updating the docs but I want to make sure the functionality is correct. The tests indicate that you don't need to add Plug.Session as a plug. Can you confirm the expected behavior?

from plug.

josevalim avatar josevalim commented on September 23, 2024

You need to add it as plug, otherwise fetch_session must fail.

from plug.

nurugger07 avatar nurugger07 commented on September 23, 2024

Ok, then there may be an issue because the following code runs without issue:

defmodule Plugger.Router do
  import Plug.Conn
  use Plug.Router

  plug :match
  plug :dispatch

  @valid_secret String.duplicate("abcdef0123456789", 8)

  get "/" do
    opts = Plug.Session.init(store: :cookie, key: "_plugger", secret: @valid_secret)
    conn = Plug.Session.call(conn, opts)
    conn = fetch_session(conn)
    conn = put_session(conn, :foo, "bar")

    foo = get_session(conn, :foo)

    send_resp(conn, 200, foo)
  end

  get "/hello" do
    opts = Plug.Session.init(store: :cookie, key: "_plugger", secret: @valid_secret)
    conn = Plug.Session.call(conn, opts)
    conn = fetch_session(conn)
    foo = get_session(conn, :foo)

    send_resp(conn, 200, "Say hello to #{foo}")
  end

  match _ do
    send_resp(conn, 404, "oops")
  end
end

from plug.

josevalim avatar josevalim commented on September 23, 2024

What you are doing manaully in the two examples above is exactly what the plug macro does! The only difference is that the plug macro caches the Plug.Session.init/1 result.

from plug.

nurugger07 avatar nurugger07 commented on September 23, 2024

Kind of. I walked through the Plug.Builder code and it appears to be doing it, however, it doesn't. The following code produces the error "cannot fetch session without a configured session plug".

defmodule Plugger.Router do
  import Plug.Conn
  use Plug.Router

  plug :match
  plug :dispatch

  @valid_secret String.duplicate("abcdef0123456789", 8)

  plug Plug.Session, store: :cookie, key: "_plugger", secret: @valid_secret

  get "/" do
    conn = fetch_session(conn)
    conn = put_session(conn, :foo, "bar")

    foo = get_session(conn, :foo)

    send_resp(conn, 200, foo)
  end

  get "/hello" do
    conn = fetch_session(conn)
    foo = get_session(conn, :foo)

    send_resp(conn, 200, "Say hello to #{foo}")
  end

  match _ do
    send_resp(conn, 404, "oops")
  end
end

from plug.

josevalim avatar josevalim commented on September 23, 2024

That's because the order matters, if you Plug.Session after plug :dispatch, the session will be added only after the route is dispatched!

from plug.

nurugger07 avatar nurugger07 commented on September 23, 2024

Ah!!! Ok, it works like a champ! As I said, there must be something I'm doing wrong because other plugs seem to be working. I know that there is mention that order is reversed but I don't believe there is anything that specifically says which order to add Plug.Session.

I'll look at updating the docs today and providing some clear examples.

from plug.

scrogson avatar scrogson commented on September 23, 2024

Also, fetch_session/1 is called for you automatically.

On Tuesday, July 1, 2014, Johnny Winn [email protected] wrote:

Ah!!! Ok, it works like a champ! As I said, there must be something I'm
doing wrong because other plugs seem to be working. I know that there is
mention that order is reversed but I don't believe there is anything that
specifically says which order to add Plug.Session.

I'll look at updating the docs today and providing some clear examples.


Reply to this email directly or view it on GitHub
#55 (comment).

from plug.

nurugger07 avatar nurugger07 commented on September 23, 2024

Thanks @josevalim! I went back to phoenix and tested a cookie session plug and it's working as expected. The gotcha was the order of loading. I'll work on the docs today to help clarify usage.

from plug.

nurugger07 avatar nurugger07 commented on September 23, 2024

@scrogson just figured that out too :)

from plug.

josevalim avatar josevalim commented on September 23, 2024

It is called automatically for you on put, but not on get afaik.

from plug.

josevalim avatar josevalim commented on September 23, 2024

@scrogson the idea is that a framework like Phoenix can always add the Session plug, but the session will only be fetch when you explicitly do it. This allows you to always plug it, but control exactly when it must be loaded.

from plug.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.