Safely Impersonating Another User
Drupal 7 will no longer be supported after January 5, 2025. Learn more and find resources for Drupal 7 sites
There are many times when you may want your code to “impersonate” another user. An example of this is when a user takes an action that triggers another process. If that other process should be done as a different user then you want to impersonate that other user.
Here is example code which is unsafe:
global $user;
$original_user = $user;
$user = user_load(array('uid' => 1));
// Take your action here where you pretend to be the user with UID = 1 (typically the admin user on a site)
// NOTE: - this is the unsafe part - if your code here fails, then the user suddenly has the permissions of UID 1!
$user = $original_user; The safe way to implement this is to use the function session_save_session() (D6) or drupal_save_session() (D7) as follows:
For D6:
global $user;
$original_user = $user;
$old_state = session_save_session();
session_save_session(FALSE);
$user = user_load(array('uid' => 1));
// Take your action here where you pretend to be the user with UID = 1 (typically the admin user on a site)
// If your code fails, it's not a problem because the session will not be saved
$user = $original_user;
session_save_session($old_state);
// From here on the $user is back to normal so it's OK for the session to be saved For D7:
global $user;
$original_user = $user;
$old_state = drupal_save_session();
drupal_save_session(FALSE);
$user = user_load(1);
// Take your action here where you pretend to be the user with UID = 1 (typically the admin user on a site)
// If your code fails, it's not a problem because the session will not be saved
$user = $original_user;
drupal_save_session($old_state);
// From here on the $user is back to normal so it's OK for the session to be saved For D8:
You may use the Account Switcher (account_switcher) service to safely impersonate another user. This service will handle the session writing that was required in Drupal 6 and Drupal 7 above.
In Drupal 8, the core Cron service will always execute as an anonymous user when it invokes cron handlers and processes queues.
// Retrieve the account switcher service. Ideally you should inject the account_switcher service into your class.
$accountSwitcher = Drupal::service('account_switcher');
$accountSwitcher->switchTo(new Drupal\Core\Session\AnonymousUserSession());
// Take your action here. If your code fails, then you should catch an exception
// and switch back (see below).
// Restore user account.
$accountSwitcher->switchBack(); or
// Retrieve the account switcher service. Ideally you should inject the account_switcher service into your class.
$accountSwitcher = Drupal::service('account_switcher');
$account = \Drupal\user\Entity\User::load(2);
$accountSwitcher->switchTo($account);
// Take your action here. If your code fails, then you should catch an exception
// and switch back (see below).
// Restore user account.
$accountSwitcher->switchBack(); An alternative to the above that is related to Menu Tree access is to use a Menu Link Tree Manipulator service. Manipulators allow you to modify or transform a given menu tree by a callable method. This would allow you, for instance, to change a give menu tree by a particular user.
// Setup manipulators array to pass into the MenuTree transform method that
// includes your module's manipulator service and method.
$manipulators = array( 'callable' => 'my_module.tree_manipulator_service::checkAccess', );
// Menu parameters
$parameters = new MenuTreeParameters();
// Transform the menu tree after loading the main menu.
$menu_tree = Drupal::service('menu.link_tree');
$tree = $menu_tree->load('main', $parameters);
$tree = $menu_tree->transform($tree, $manipulators); Help improve this page
You can:
- Log in, click Edit, and edit this page
- Log in, click Discuss, update the Page status value, and suggest an improvement
- Log in and create a Documentation issue with your suggestion