2

I'm writing a custom script that requires a proper Drupal 8 user session to work. This is the current version:

<?php

use Drupal\Core\DrupalKernel;
use Symfony\Component\HttpFoundation\Request;

$drupal_root = __DIR__;
define('DRUPAL_DIR', $drupal_root);

// Specify relative path to the drupal root.
$autoloader = require_once DRUPAL_DIR . '/autoload.php';
$request = Request::createFromGlobals();

// Bootstrap drupal to different levels
$kernel = DrupalKernel::createFromRequest($request, $autoloader, 'prod');
$kernel->boot();
$kernel->handlePageCache($request);
$kernel->prepareLegacyRequest($request);

// get session handler and retrieve session details
$session_handler = \Drupal::getContainer()->get('session_handler.storage');
$session_id = $session_handler->getId();
$logged_in = (bool) $session_handler->read($session_id);

// inspect values
var_dump($request->getSession());
var_dump($session_id);
var_dump($logged_in); exit;

I'd expect $request->getSession() to return something, $session_id to be the Drupal's session id, and the $logged_in variable to be truthy. Instead I keep getting this output:

NULL string(0) "" bool(false)

Update 1: I executed this on a browser, which I have an active session with my Drupal. This script is placed in a subfolder of the Drupal installation, so it should not be a cookie path issue.

Update 2: Added var_dump($request->getSession()) to the script.

4
  • Does the context you're executing this script in have an active session (and a method to carry it through to subsequent requests, like a browser)? For example if you're executing this via the CLI, that won't happen
    – Clive
    Sep 26, 2019 at 9:01
  • @Clive: I executed this on a browser, which I have an active session with my Drupal. This script is placed in a subfolder of the Drupal installation, so it should not be a cookie path issue. Sep 26, 2019 at 9:02
  • Is $request->getSession() also empty?
    – Clive
    Sep 26, 2019 at 9:09
  • var_dump($request->getSession()); returns NULL. Sep 26, 2019 at 9:12

1 Answer 1

1

This is the code I came up with in the end. It works.

Feel free to suggest a more concise version :-)

<?php

use Drupal\Core\DrupalKernel;
use Symfony\Component\HttpFoundation\Request;

$drupal_root = realpath(__DIR__ . '/../');
$autoloader = require_once $drupal_root . '/autoload.php';

// Make sure Drupal operates correct when handle request instead of internal server error and twig error
chdir($drupal_root);

$kernel = new DrupalKernel('prod', $autoloader);

// Note: The session_name is generated from the string "{domain}/{script basepath}".
// Need to override the script filename and script name before creating request.
$_SERVER['SCRIPT_FILENAME'] = $drupal_root . '/index.php';
$_SERVER['SCRIPT_NAME'] = '/index.php';
$request = Request::createFromGlobals();
// Note: may restore script_name and script_filename after this line.

// This handle process would chain up and initialize all services
// in container, include the session handler.
$kernel->handle($request);

// now we can use session normally
$session_handler = \Drupal::getContainer()->get('session_handler.storage');
$session_id = $session_handler->getId();
$logged_in = (bool) $session_handler->read($session_id);

// restore app
chdir(__DIR__);
1
  • 1
    This has a few issues: 1) Drupal generates 500 error + twig error. 2) Generates page not found /app/index.php. 3) The session is not unserilized after read (no object). 4) the app is in a wrong state (you made not for that). Jan 19, 2020 at 13:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.