Drupal 9: Using The Private Temporary Store Service

The Drupal tempstore.private service is used to allow temporary user data that is available from one web request to the next. It is intended to be used for non-cache data that cannot easily be rebuild. This includes work in progress data that isn't in the position to be saved permanently.

The temporary store is a key value/store and cam therefore store anything from a single value to a serialised object.

The tempstore.private service is really a factory (called PrivateTempStoreFactory) that will allow you to create instance of a PrivateTempStore object. It's this object that can be used to manage the data in the store. If you are familiar with the way that configuration factories work then this will seem familiar.

Using the temporary storage is quite straightforward, the service has a get() method that takes the name of the temporary store you want to use. What you call it is up to you, but it is best to namespace this so that you can easily tell where the temporary store came from. You can also add information like what sort of temporary store you are using, but don't add any user identifiable information for the key.

Once the PrivateTempStore object has been created you can then use it to set whatever data you might want to set.

/** @var \Drupal\Core\TempStore\PrivateTempStore $store */
$store = \Drupal::service('tempstore.private')->get('mymodule');
$store->set('var_name', $data);

To get the data back again just use the get() method.

/** @var \Drupal\Core\TempStore\PrivateTempStore $store */
$store = \Drupal::service('tempstore.private')->get('mymodule');
$data = $store->get('var_name');

You can create a private temporary store with the user in mind by adding the user details to the name of the key. All keys, however, "belong" to a user, so it is not possible for one user to fetch the temporary store of another user. It is a private temporary store after all :)

If the user is not logged in then a session instance is started so that the anonymous user can still have a private store.

You can also find out any metadata about a value in the private temporary storage by using the getMetadata() method.

/** @var \Drupal\Core\TempStore\PrivateTempStore $store */
$store = \Drupal::service('tempstore.private')->get('mymodule');
$metadata = $store->getMetadata('var_name');

This will return a Lock object that contains the user who created the private temporary storage and the time that they created it.

Drupal\Core\TempStore\Lock Object
(
    [ownerId:Drupal\Core\TempStore\Lock:private] => 1
    [updated:Drupal\Core\TempStore\Lock:private] => 1657372409
)

By default, the data will stay in the temporary store for a week (604800 seconds). If you wish to delete the private temporary storage value before the expiry date then you can do so with the delete() method.

​/** @var \Drupal\Core\TempStore\PrivateTempStore $store */
$store = \Drupal::service('tempstore.private')->get('mymodule');
$store->delete('var_name');

If you want to change the expiry date to be a different value then you'll need to override the tempstore.private service and pass in a different value as the expiry time. The following shows a service definition that overrides the default expiry time to 200 seconds (the last parameter in the arguments array).

services:
  mymodule_tempstore.private:
    class: Drupal\Core\TempStore\PrivateTempStoreFactory
    arguments: ['@keyvalue.expirable', '@lock', '@current_user', '@request_stack', 200]
    tags:
      - { name: backend_overridable }

This service can be used just like the tempstore.private service, but needs to be created using the new service name.

/** @var \Drupal\Core\TempStore\PrivateTempStore $store */
$store = \Drupal::service('mymodule_tempstore.private')->get('mymodule');

Examples Of tempstore.private In Use

Whilst all of that theory is interesting, I thought it would be good to show a few examples of the tempstore.private service in use.

Temporary Encryption Keys

One of the only times I have used this service was when dealing with caching generated PDFs from a third party API. The PDF documents contained sensitive information and needed to be stored in an encrypted state on disk. When the user asked for a copy of the PDF the site would pull it from the API, encrypt it and store the encrypted file on the server.

Rather than use the user profile or a cache to store the encryption key we opted to use the tempstore.private service. This meant that the key wasn't stored permanently in the database but the user would still have access to decrypt the document until the key expired. We also overrode the default expiry time so that the key expired sooner, rather than have it sat in storage for a week.

If the user attempted to read the PDF document and it was found that the key had expired, then we just pulled the PDF from the remote API again. The user never knew about the encryption and the API didn't need to serve repeated requests for the PDF doument if the user happened to download the document more than once before the key expired.

Views Bulk Operations

The awesome Views Bulk Operations (VBO) module makes use of the tempstore.private service to store some variables when handling the bulk operations form.

The ViewsBulkOperationsBulkForm form in the module uses the private temporary store to keep hold on the options selected when the user submits a bulk operatioins form. This includes the list of items that are are being processed by the form and means that even if the form fails half way through the data it created to process the form won't be around for very long. If the module used a queue system (or similar) then code would need to be written to empty the queue of expired items.

Also, as the bulk operation is only important for the user performing the action then the private store is ideal as it automatically means that the store belongs to that user.

SAML Authentication

I have used the SAML Authentication module with great success in the past when setting up SimpleSAMLPHP and Drupal.

The SamlService class that controls communication between the identity provider and the SAML toolkit uses the private temporary store to store SAML session information for the user as they authenticate with the service. These values are stored until the user logs out, at which point they are retrieved from the store and used to log the user out of the SAML service.

Doing things this way means that the Drupal authentication system and the SAML authentication system can be treated separately. The SAML authentication essentially hands over the authentication of the user to Drupal and allows Drupal to handle the user's session. As the user logs out their Drupal session is stopped and the values in the private temporary store are used to log the user out of the upstream SAML identity provider.

Add new comment

The content of this field is kept private and will not be shown publicly.
CAPTCHA
10 + 2 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.