bungle / lua-resty-session

Session library for OpenResty – flexible and secure
BSD 2-Clause "Simplified" License
320 stars 111 forks source link

Session lock always times out when using shared memory? #91

Closed mamacdon closed 4 years ago

mamacdon commented 4 years ago

I'm using lua-resty-session-2.26 indirectly via lua-resty-openidc-1.7.2. I'm using shm storage to keep sessions in memory.

I'm having a problem when the web browser already has a session cookie, and it makes several /api requests in close succession. The first request will immediately be recognized as having a session, no problem there.

The second request hangs for 5 seconds, then causes a token refresh to my identity provider, and generates a new session cookie. This slows down my web UI, as every request after the first one is very slow.

From the logs, I can see it's waiting on this line where openidc calls session.start(). It hangs here for 5 seconds, then receives a session having session.present == nil, which makes it think there's no session at all.

local session, session_error = r_session.start(session_opts)     -- hangs here

I noticed that $session_shm_lock_timeout controls the amount of time that it hangs. So it seems like the locking mechanism times out on every request after the initial one. If I wait for $session_shm_lock_exptime seconds between requests, then there's no timeout, and the 2nd request works fine (but in real life I can't control this, the client could send us many requests very quickly).

Setting $session_shm_uselocking: off avoids the issue completely, but I don't understand the implications. Is locking necessary when using shared memory? Is this supposed to work?


Configuration

nginx.conf:

lua_shared_dict sessions 10m;

http {
  ……

  location /api {
    include conf/session.conf;
    proxy_pass http://backend;
  }

  # redirect_uri callback
  location /welcome {
    include conf/session.conf;
  }
}

conf/session.conf:

set $session_storage           shm;
set $session_shm_store         sessions;
access_by_lua_file auth.lua;

auth.lua

local opts = {
  discovery = "https://my-id-provider/.well-known/openid-configuration",
  redirect_uri_path = "/welcome",
  scope = " ",
  redirect_uri_scheme = "https",
}

local res, err = require("resty.openidc").authenticate(opts)

ngx.req.set_header("Authorization", res.access_token)
bungle commented 4 years ago

I am currently working on 3.0 that will fix some bugs in releasing the locks. Otherwise remember to always save the started session:

local session = require "resty.session".start()
session.data.x = "blaa"
session:save()
-- OR
session:close()
mamacdon commented 4 years ago

My bad: I misunderstood how lua-resty-openidc makes use of the session. I thought it was closed automatically, but it's not: the caller is responsible for calling session.close(). That explains why the lock was never closed.

I will close this issue