1

I am trying to authenticate users as below. I don't get any error, but it doesn't log in users.

autoLogin.php is located in the root folder. Visiting http://example.com/drupal8/autoLogin.php shows me the Login required page every time.

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

$autoloader = require_once 'autoload.php';

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

$request = Request::createFromGlobals();
$response = $kernel->handle($request);

$uid = 1; 
$user = Drupal\user\Entity\User::load(1); 
$kernel->prepareLegacyRequest($request);
user_login_finalize($user);
$response->send();
$kernel->terminate($request, $response);
1
  • 2
    The code should throw an error about the user_login_finalize() function, since the User module hasn't been loaded, yet.
    – apaderno
    Jan 23, 2021 at 21:44

1 Answer 1

1

The code shown in the question would throw an error about user_login_finalize() not being defined. The code isn't loading the User module and the DrupalKernel class doesn't load any module.

I generally use the code shown in authorize.php as guideline on how to bootstrap and programmatically log in a user. In this case, to programmatically log in the user whose ID is 1, I would use the following code.

use Drupal\Core\DrupalKernel;
use Drupal\user\Entity\User;
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Route;

$autoloader = (require_once 'autoload.php');

try {
  $request = Request::createFromGlobals();
  $kernel = DrupalKernel::createFromRequest($request, $autoloader, 'prod');
  $kernel->boot();

  // A route is required for route matching.
  $request->attributes->set(RouteObjectInterface::ROUTE_OBJECT, new Route('<none>'));
  $request->attributes->set(RouteObjectInterface::ROUTE_NAME, '<none>');
  $kernel->preHandle($request);

  if (PHP_SAPI !== 'cli') {
    $request->setSession($kernel->getContainer()->get('session'));
  }
} catch (HttpExceptionInterface $e) {
  $response = new Response('', $e->getStatusCode());
  $response->prepare($request)->send();
  exit;
}

\Drupal::moduleHandler()->addModule('system', 'core/modules/system');
\Drupal::moduleHandler()->addModule('user', 'core/modules/user');
\Drupal::moduleHandler()->load('system');
\Drupal::moduleHandler()->load('user');
if ($account = User::load(1)) {
  \Drupal::currentUser()->setAccount($account);
  // Add your code.
  $response->setStatusCode(200);
  $response->send();
}  

Since it seems you are trying to access a specific page after logging in the user #1, it's probable you need to change the two lines following the A route is required for route matching. comment and use a different route name.

2
  • As side note, I would rather not bootstrap Drupal from an external script. I would create a custom module with its own route which would execute the code I need. Even Drupal core stopped to use an external script (cron.php) to run the cron tasks and instead added a route for running them (system.cron).
    – apaderno
    Jan 24, 2021 at 9:42
  • Yes, I am planning to create a custom module but I want to make sure it's working beforehand. It gives Error: Call to a member function setStatusCode() on null so I added $response = $kernel->handle($request); right after 'Add your code' line. It doesn't log me in though. It still shows the app as unauthenticated.
    – likeachamp
    Jan 25, 2021 at 18:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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