getgrav / grav-plugin-admin

Grav Admin Plugin
http://getgrav.org
MIT License
355 stars 222 forks source link

grav-admin; forced logout, invalid security token errors, inconsistent behavior #2375

Open wilson0x4d opened 9 months ago

wilson0x4d commented 9 months ago

I think this is a problem with sessions, but i'm all of 4 hours invested in grav and wouldn't know if this is a config problem or a code problem: we get forcefully logged out of grav-admin and receive "Invalid Security Token" errors when attempting to log back in.

we have deployed grav to a kubernetes cluster (that runs dozens of other services without fail.) we noticed when we scale the deployment down to just one pod/instance it seems to work as expected. at least until we scale it back out to 2 or more instances (at which point HTTP requests are round-robin load-balanced to each instance.)

for our setup, each instance/pod uses the a shared /config (via NFS mount, single volume, no symlinks, root privs. what one instance sees all instances see.)

this is on a fresh install of grav using the 'official' lsio image, no customizations. this is out of the box behavior.

  1. incognito makes no difference.
  2. browser flavor makes no difference.
  3. clearing app data (cache, cookies, db, etc/all) makes no difference.
  4. deprovision + redeploy makes no difference.
  5. grav cache clear makes no difference.
  6. fiddling with system.yaml settings has made no difference.

when we leave the deployment scaled to just a single grav instance/pod grav-admin works without any problems for extended periods (hours.) the moment we scale the deployment back up we get logged out and cannot log back in, or if we get lucky and manage to get logged in, we are almost immediately logged back out. sometimes the login prompt just throws us directly back to the login prompt (with no error message.)

nothing in grav logs, php logs, nginx logs.

how can we make this work correctly? scaling down to 1 node isn't a solution, and giving users access to the NFS volume for content editing and ditching grav-admin and login plugins also isn't a solution. the developer in me is saying we need session management that is portable (works in a web farm) but none of the options i can edit appear to accomplish this. typically this is done with a cookie, sometimes with a query param, and in a worse-case scenario a secondary system is used to store session state (like a database, nosql/doc db, or a file share.)

if there is information i can share here to help devs/others diagnose, point me in the right direction and I will get it to you.

if this simply isn't something grav/grav-admin supports that's an acceptable answer, we just need to know so we can move forward with implementing our own solution. but we'd really like to see grav work out for us. 👍

thanks!

wilson0x4d commented 9 months ago

i wanted to make it clear which container image we are using for SEO purposes, this may help others using the same thing having the same problem find the solution more easily:

https://hub.docker.com/r/linuxserver/grav aka linuxserver.io/grav

..using the latest image/release.

wilson0x4d commented 9 months ago

it looks like i may have resolved the issue. i'm not a PHP dev so it took some time to go through grav's session code, the php docs, etc. this is perhaps obvious to a seasoned php dev.

it appears php uses files to store sessions by default, and, the files are created in a temp directory (/tmp i believe? i could be mistaken.) near as i can tell it doesn't appear grav tampers with this, thankfully.

to achieve session portability for our cluster i only needed to edit the session.save_path php.ini setting.

this is possible from /config/php/php-local.ini -- i am not sure if this is specific to the lsio container image, or if this is something grav establishes as part of its standard deployment. if a grav dev could clarify, it may help others in the future.

for completeness, my php-local.ini now looks like this:

session.save_handler=files
session.save_path=/config/sess

in this context sess/ can be anything, i chose this for obviousness for when another human has to figure this setup out later.

i had to precreate the sess/ directory and chown it to the correct uid/gid, i am fairly certain the uid/gid pair here is lsio-specific (mapping to a least-privilege abc user and group specific to the container image.) for others trying this, basically the same user/group that is applied to www/* is what needs access to sess/. since i am setting this outside of the container i am using numeric values instead of the human-friendly names since these specific user/group values don't exist where i am doing admin:

mkdir /config/sess
chown 911:911 /config/sess

it is worth noting that for my lsio containers i have an NFS volume mounted to /config and so i was able to do this on the NFS volume. this, incidentally, allows all pods to access a shared sess/ directory.

seems to be working for me, so far no issues, some small performance penalty hitting the NFS volume for session but it's negligible.

hope this helps someone else out there!

jooru commented 7 months ago

Hello! Are you sure you have set an unique name for session cookies for each Grav instance? This is configured in Admin Panel › Configuration › Session › Name › <unique-name-per-domain> Good luck! )