AnswerBun.com

Using an authentication provider to keep a user permanently logged in eventually causes session problems

Drupal Answers Asked by joachim on December 5, 2020

Because I got fed up of having to log in to my local development sites every however long, I tried making a simple custom module that just has an Authentication Provider service that always returns user 1, like this:

  /**
   * {@inheritdoc}
   */
  public function applies(Request $request) {
    return TRUE;
  }

  /**
   * {@inheritdoc}
   */
  public function authenticate(Request $request) {
    return $this->entityTypeManager->getStorage('user')->load(1);
  }

The idea being that with this module enabled, every page load considers the authenticated user to be user 1. In theory, I’d be logged in for ever!

However, after a few weeks of this working fine, all my form submissions broke! Every form submission fails with:

The form has become outdated. Press the back button, copy any unsaved work in the form, and then reload the page

This turns out to be because CsrfTokenGenerator::validate() fails. Specifically, the $seed in this bit is just NULL:

  public function validate($token, $value = '') {
    $seed = $this->sessionMetadata->getCsrfTokenSeed();
    if (empty($seed)) {
      return FALSE;
    }

I presume it’s because the session has expired in some way? The time this has taken to stop working is roughly the amount of time it would have taken the site to log me out automatically.

How can I fix this?

One Answer

I presume it's because the session has expired in some way?

First you need to understand how this happens.

Configuring Garbage Collection

When a session opens, PHP will call the gc handler randomly according to the probability set by session.gc_probability / session.gc_divisor. For example if these were set to 5/100 respectively, it would mean a probability of 5%. Similarly, 3/4 would mean a 3 in 4 chance of being called, i.e. 75%.

If the garbage collection handler is invoked, PHP will pass the value stored in the php.ini directive session.gc_maxlifetime. The meaning in this context is that any stored session that was saved more than gc_maxlifetime ago should be deleted. This allows one to expire records based on idle time.

However, some operating systems (e.g. Debian) do their own session handling and set the session.gc_probability variable to 0 to stop PHP doing garbage collection. That's why Symfony now overwrites this value to 1.

If you wish to use the original value set in your php.ini, add the following configuration:

# config/packages/framework.yaml
framework:
    session:
        gc_probability: null

Source: Symphony's official docs on Configuring Sessions and Save Handlers

In Drupal 8 & 9 you can see these gc settings in default.services.yml

Possible Solutions on how to stay logged in longer.

In /sites/default/settings.php uncomment

 if (file_exists($app_root . '/' . $site_path . '/settings.local.php')) {
   include $app_root . '/' . $site_path . '/settings.local.php';
 }

then copy /sites/example.settings.local.php and rename to /sites/default/settings.local.php

Now you can use /sites/development.services.yml to override those settings, for example

(I used these numbers for testing so it logs me out after 2 seconds):

parameters:
  session.storage.options:
    gc_probability: 1
    gc_divisor: 1
    gc_maxlifetime: 2
    cookie_lifetime: 2

I tried setting gc_probability to 0 or null, which should stop it, but the gc() function still fired. Perhaps it's reading the value from php.ini

So alternatively you could set the gc_maxlifetime and cookie_lifetime to not expire decades from now. See set a cookie to never expire.

Answered by No Sssweat on December 5, 2020

Add your own answers!

Related Questions

How to programmatically reference entities?

1  Asked on October 26, 2021 by sveggen

   

custom action plugin with ConfigurationForm

1  Asked on October 26, 2021

     

grouped paragraphs by field not filtering to current language

1  Asked on October 26, 2021 by turpentyne

     

How do I migrate node entity references?

0  Asked on October 26, 2021 by alexandre

     

Form textfield AJAX validation “deletes” injected services to form

1  Asked on October 26, 2021 by pedro-tentugal

   

Allowing anonymous users to contact node authors

1  Asked on October 26, 2021 by aroopk

     

How to cache a view for all users of a role?

1  Asked on October 26, 2021 by ktrev

     

Is it feasible to migrate by only migrating content?

2  Asked on October 26, 2021 by benjen

   

Get the breadcrumbs for a specific node other than the current

1  Asked on October 26, 2021 by nils-riedemann

     

Views exposed filters without “Apply” button

3  Asked on October 26, 2021

   

Saving form data and running custom queries in mysql

1  Asked on October 26, 2021 by benn-moffat

     

Add additional fields to the postal address

1  Asked on October 26, 2021 by jay-haase

 

Ask a Question

Get help from others!

© 2022 AnswerBun.com. All rights reserved. Sites we Love: PCI Database, MenuIva, UKBizDB, Menu Kuliner, Sharing RPP, SolveDir