diff --git a/config/install/session_cache.settings.yml b/config/install/session_cache.settings.yml
new file mode 100644
index 0000000..6c316ac
--- /dev/null
+++ b/config/install/session_cache.settings.yml
@@ -0,0 +1,3 @@
+storage_method: 1
+expire_period: 7
+sid_source: 0
diff --git a/lib/Drupal/session_cache/Form/SessionCacheSettingsForm.php b/lib/Drupal/session_cache/Form/SessionCacheSettingsForm.php
deleted file mode 100644
index b52d3de..0000000
--- a/lib/Drupal/session_cache/Form/SessionCacheSettingsForm.php
+++ /dev/null
@@ -1,81 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\session_cache\Form\SessionCacheSettingsForm.
- */
-
-namespace Drupal\session_cache\Form;
-
-use Drupal\system\SystemConfigFormBase;
-
-/**
- * Menu callback and form-builder for session cache configuration settings.
- */
-class SessionCacheSettingsForm extends SystemConfigFormBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormID() {
-    return 'session_cache_settings';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildForm(array $form, array &$form_state) {
-    // Not sure which of these first two lines is better
-    //$this->configFactory->get('session_cache.settings')
-    $config = config('session_cache.settings');
-
-    $form['storage_method'] = array(
-      '#type' => 'radios',
-      '#title' => t('Where should user session data be stored?'),
-      '#default_value' => $config->get('storage_method') ?: SESSION_CACHE_STORAGE_SESSION,
-      '#options' => array(
-        SESSION_CACHE_STORAGE_COOKIE  => t("on the user's computer, in a cookie"),
-        SESSION_CACHE_STORAGE_DB_CORE => t("on the server, on core's cache database"),
-        SESSION_CACHE_STORAGE_SESSION => t('on the server, in $_SESSION memory')
-      ),
-      '#description' => t('The first two mechanisms will NOT write to or read from $_SESSION so are generally a good choice when your site uses Varnish or similar page caching engine.')
-    );
-
-    $expire_period = (float) $config->get('expire_period');
-    if ($expire_period <= 0.0) {
-      $expire_period = SESSION_CACHE_DEFAULT_EXPIRATION_DAYS;
-    }
-    $form['expire_period'] = array(
-      '#type' => 'textfield',
-      '#size' => 4,
-      '#title' => t('Expiration time for the database cache and cookies created via this module'),
-      '#field_suffix' => t('days'),
-      '#default_value' => $expire_period,
-      '#description' => t('You may use decimals, eg 0.25 equates to 6 hours.<br/>$_SESSION expiration is set via the server configuration. See the <em>sites/default/settings.php</em> file for details.')
-    );
-
-    $form['use_uid_as_sid'] = array(
-      '#type' => 'checkbox',
-      '#title' => t("Remember the user's session from one browser to the next"),
-      '#default_value' => $config->get('use_uid_as_sid') ?: FALSE,
-      '#description' => t('Applies to authenticated users only and does not work for the cookie and $_SESSION storage mechanisms.')
-    );
-
-    return parent::buildForm($form, $form_state);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, array &$form_state) {
-    // Not sure which of these first two lines is better
-    //$this->configFactory->get('session_cache.settings')
-    config('session_cache.settings')
-      ->set('storage_method', $form_state['values']['storage_method'])
-      ->set('expire_period',  $form_state['values']['expire_period'])
-      ->set('use_uid_as_sid', $form_state['values']['use_uid_as_sid'])
-      ->save();
-
-    parent::submitForm($form, $form_state);
-  }
-}
diff --git a/session_cache.admin.inc b/session_cache.admin.inc
new file mode 100644
index 0000000..f4a1342
--- /dev/null
+++ b/session_cache.admin.inc
@@ -0,0 +1,53 @@
+<?php
+
+/**
+ * @file
+ * session_cache.admin.inc
+ */
+
+/**
+ * Menu callback for admin settings.
+ *
+ * Contrib modules can add more options by implementing hook_form_alter().
+ */
+function session_cache_admin_config() {
+  $form['session_cache_storage_method'] = array(
+    '#type' => 'radios',
+    '#title' => t('Where should user session data be stored?'),
+    '#default_value' => \Drupal::config('session_cache.settings')->get('session_cache_storage_method'),
+    '#options' => array(
+      SESSION_CACHE_STORAGE_COOKIE  => t("on the user's computer, in a cookie"),
+      SESSION_CACHE_STORAGE_DB_CORE => t("on the server, on core's cache database"),
+      SESSION_CACHE_STORAGE_SESSION => t('on the server, in $_SESSION memory'),
+    ),
+    '#description' => t('When using Varnish or similar page caching engine for anonymous users, do not use $_SESSION and have a page exclusion strategy in place.'),
+  );
+
+  $options = array(
+    SESSION_CACHE_COOKIE_FOR_SID => t('via their cookie'),
+    SESSION_CACHE_UID_FOR_SID => t('via their login id, via cookie for anonymous users (works cross-browser for authenticated users)'),
+    SESSION_CACHE_IP_ADDRESS_FOR_SID => t('via their IP address')
+  );
+  $form['session_cache_sid_source'] = array(
+      '#type' => 'radios',
+      '#title' => t('Method for identifying the user in database and file-based storage methods'),
+      '#options' => $options,
+      '#default_value' => \Drupal::config('session_cache.settings')->get('session_cache_sid_source'),
+      '#description' => t('None of the above apply to the $_SESSION and cookie storage mechanisms.'),
+  );
+
+  $expire_period = (float) \Drupal::config('session_cache.settings')->get('session_cache_expire_period');
+  if ($expire_period <= 0.0) {
+    $expire_period = SESSION_CACHE_DEFAULT_EXPIRATION_DAYS;
+  }
+  $form['session_cache_expire_period'] = array(
+    '#type' => 'textfield',
+    '#size' => 4,
+    '#title' => t('Expiration time for the database cache and cookies created via this module'),
+    '#field_suffix' => t('days'),
+    '#default_value' => $expire_period,
+    '#description' => t('You may use decimals, eg 0.25 equates to 6 hours.<br/>$_SESSION expiration is set via the server configuration. See the <em>sites/default/settings.php</em> file for details.'),
+  );
+
+  return system_settings_form($form);
+}
diff --git a/session_cache.api.php b/session_cache.api.php
new file mode 100644
index 0000000..7f6bc5c
--- /dev/null
+++ b/session_cache.api.php
@@ -0,0 +1,100 @@
+<?php
+
+/**
+ * @file
+ * API documentation for Session Cache API module.
+ *
+ * Cookies and database session caches created through this API expire after a
+ * UI-configurable number of hours or days. $_SESSIONs expire according to the
+ * global configuration -- see the comments in
+ * sites/default/files/default.settings.php.
+ */
+
+/**
+ * Write data to the user session, whatever the storage mechanism may be.
+ *
+ * @param string $bin
+ *   Unique id, eg a string prefixed by the module name.
+ * @param mixed $data
+ *   A number or string, an object, a multi-dimensional array etc.
+ *   $bin is the identifier you choose for the data you want to store. To
+ *   guarante uniqueness, you could prefix it with the name of the module that
+ *   you use this API with.
+ *   Use NULL to erase the bin; it may be auto-recreated and refilled at any
+ *   time by calling the function again with a non-NULL data argument.
+ */
+function session_cache_set($bin, $data) {
+  // See the following modules for examples:
+  // o IP Geolocation Views & Maps.
+  // o Views Global Filter.
+}
+
+/**
+ * Read data from the user session, given its bin id.
+ *
+ * @param string $bin
+ *   unique id eg a string prefixed by the module name
+ *
+ * @return mixed
+ *   the cache data
+ */
+function session_cache_get($bin) {
+  // See the following modules for examples:
+  // o IP Geolocation Views & Maps.
+  // o Views Global Filter.
+}
+
+/**
+ * @addtogroup hooks
+ * @{
+ */
+
+/**
+ * Implement this set-hook to complete your own storage mechanism.
+ *
+ * @param int $storage_method
+ *   the storage method
+ * @param string $bin
+ *   the name of the bin under which to store $data
+ * @param mixed $data
+ *   the data to store
+ */
+function hook_session_cache_set($storage_method, $bin, $data) {
+  if ($storage_method != MYMODULE_SESSION_STORAGE) {
+    return;
+  }
+  // Store $data in $bin, using your module's mechanism.
+  // For an example see the submodule: session_cache_file.module
+}
+
+/**
+ * Implement this get-hook to complete your own storage mechanism.
+ *
+ * @param int $storage_method
+ *   the storage methd
+ * @param string $bin
+ *   the name of the bin to retrieve cached data from
+ *
+ * @return mixed
+ *   the cached data
+ */
+function hook_session_cache_get($storage_method, $bin) {
+  if ($storage_method != MYMODULE_SESSION_STORAGE) {
+    return NULL;
+  }
+  // ... your retrieval mechanism goes here.
+  $data = "your data based on $bin";
+  return $data;
+}
+
+/**
+ * Implement this hook to make your storage mechanism selectable in the UI.
+ */
+function hook_form_session_cache_admin_config_alter(&$form, &$form_state) {
+  $form['session_cache_storage_method']['#options'][MYMODULE_SESSION_STORAGE]
+    = t('my great storage method');
+}
+
+/**
+ * @} End of "addtogroup hooks".
+ */
diff --git a/session_cache.info.yml b/session_cache.info.yml
index 0a0cafc..d1c1d05 100644
--- a/session_cache.info.yml
+++ b/session_cache.info.yml
@@ -1,6 +1,6 @@
 name: Session Cache API
-type: module
 description: A super simple API that avoids $_SESSION to offer caching engine friendly ways to save and recall user state.
 version: VERSION
 core: 8.x
 configure: admin/config/development/session-cache
+type: module
diff --git a/session_cache.install b/session_cache.install
deleted file mode 100644
index 38d225b..0000000
--- a/session_cache.install
+++ /dev/null
@@ -1,23 +0,0 @@
-<?php
-
-/**
- * @file
- * session_cache.install
- */
-
-/**
- * Implements hook_schema().
- *
- * This creates the 'cache_session_cache' table in drupal_install_schema()
- * This table can then be used in cache('session_cache')->set(...) and
- * cache('session_cache')->get(...) calls.
- * The table is dropped via drupal_uninstall_schema() when the module is
- * uninstalled.
- */
-function session_cache_schema() {
-  // Use the generic cache table for caching things not separated out into
-  // their own tables. Contrib modules may also use this to store cached items.
-  $schema['cache_session_cache'] = system_schema_cache_8007();
-  $schema['cache_session_cache']['description'] = 'Cache table for Session Cache API';
-  return $schema;
-}
diff --git a/session_cache.links.menu.yml b/session_cache.links.menu.yml
new file mode 100644
index 0000000..b88203e
--- /dev/null
+++ b/session_cache.links.menu.yml
@@ -0,0 +1,5 @@
+session_cache.admin_config:
+  route_name: session_cache.admin_config
+  title: 'Session Cache API'
+  description: 'Select the session storage mechanism.'
+  parent: system.admin_config_development
diff --git a/session_cache.module b/session_cache.module
index 3b7e453..38ca716 100644
--- a/session_cache.module
+++ b/session_cache.module
@@ -16,6 +16,10 @@ const SESSION_CACHE_STORAGE_COOKIE  = 3;
 const SESSION_CACHE_STORAGE_DB_CORE = 2;
 const SESSION_CACHE_STORAGE_SESSION = 1;
 
+const SESSION_CACHE_COOKIE_FOR_SID     = 0;
+const SESSION_CACHE_UID_FOR_SID        = 1;
+const SESSION_CACHE_IP_ADDRESS_FOR_SID = 2;
+
 const SESSION_CACHE_DEFAULT_EXPIRATION_DAYS = 7.0;
 
 /**
@@ -29,7 +33,7 @@ function session_cache_set($bin, $data) {
   if (!isset($bin)) {
     return;
   }
-  $method = config('session_cache.settings')->get('storage_method') ?: SESSION_CACHE_STORAGE_SESSION;
+  $method = \Drupal::config('session_cache.settings')->get('storage_method');
 
   switch ($method) {
 
@@ -52,33 +56,35 @@ function session_cache_set($bin, $data) {
     case SESSION_CACHE_STORAGE_DB_CORE:
       $sid = session_cache_get_sid();
       if ($data == NULL) {
-        cache('session_cache')->delete("$bin:$sid");
+        \Drupal::cache('cache_session_cache')->invalidate("$bin:$sid");
       }
       else {
-        cache('session_cache')->set("$bin:$sid", $data, session_cache_expiration_time());
+        \Drupal::cache('cache_session_cache')->set("$bin:$sid", $data, session_cache_expiration_time());
       }
       return;
 
     case SESSION_CACHE_STORAGE_SESSION:
-      $_SESSION[$bin] = $data; // $data==NULL means unset()
+      // $data == NULL means unset().
+      $_SESSION[$bin] = $data;
       return;
 
     default:
-      module_invoke_all('session_cache_set', $method, $bin, $data);
+      \Drupal::moduleHandler()->invokeAll('session_cache_set', [$method, $bin, $data]);
   }
 }
 
 /**
  * Read data from the user session, given its bin id.
  *
- * @param string $bin, unique id eg a string prefixed by the module name
+ * @param string $bin
+ *   unique id eg a string prefixed by the module name
  */
 function session_cache_get($bin) {
 
   if (!isset($bin)) {
     return NULL;
   }
-  $method = config('session_cache.settings')->get('storage_method') ?: SESSION_CACHE_STORAGE_SESSION;
+  $method = \Drupal::config('session_cache.settings')->get('storage_method');
 
   switch ($method) {
 
@@ -88,14 +94,14 @@ function session_cache_get($bin) {
 
     case SESSION_CACHE_STORAGE_DB_CORE:
       $sid = session_cache_get_sid();
-      $cached = cache('session_cache')->get("$bin:$sid");
-      return is_object($cached) ? $cached->data : NULL;
+      $cache = \Drupal::cache('cache_session_cache')->get("$bin:$sid");
+      return is_object($cache) ? $cache->data : NULL;
 
     case SESSION_CACHE_STORAGE_SESSION:
       return isset($_SESSION) && isset($_SESSION[$bin]) ? $_SESSION[$bin] : NULL;
 
     default:
-      return module_invoke_all('session_cache_get', $method, $bin);
+      return \Drupal::moduleHandler()->invokeAll('session_cache_get', [$method, $bin]);
   }
 }
 
@@ -103,7 +109,7 @@ function session_cache_get($bin) {
  * Implements hook_cron().
  */
 function session_cache_cron() {
-  if (config('session_cache.settings')->get('storage_method') == SESSION_CACHE_STORAGE_DB_CORE) {
+  if (\Drupal::config('session_cache.settings')->get('storage_method') == SESSION_CACHE_STORAGE_DB_CORE) {
     // Don't believe we need to do anything. When a cache item has expired,
     // after the time provided in the cache()->set() call, the item is up for
     // grabs by the garbage collector at any time.
@@ -116,18 +122,18 @@ function session_cache_cron() {
  *
  * Typically only called when a database storage mechanism is used.
  *
- * @return sid
+ * @return string $sid
  */
 function session_cache_get_sid() {
   global $user;
 
-  if (!empty($user->uid) && config('session_cache.settings')->get('use_uid_as_sid')) {
+  if (!empty($user->uid) && \Drupal::config('session_cache.settings')->get('use_uid_as_sid')) {
     return 'user' . $user->uid; // good if concurrent sessions for the same authenticated user are NOT required
   }
   if (empty($_COOKIE['Drupal_session_cache_sid'])) {
 
     // Don't use core's session id. Security not a problem, so keep it short.
-    $sid = drupal_substr(session_id(), 0, 12);
+    $sid = \Drupal\Component\Utility\Unicode::substr(session_id(), 0, 12);
     // If setcookie() fails, then everything still works, but a new session will
     // be created when logging in or out.
     // Don't use "global $cookie_domain", as it may contain '.localhost', which
@@ -141,19 +147,13 @@ function session_cache_get_sid() {
   return $sid;
 }
 
-function session_cache_expiration_time() {
-  $expire_period_days = config('session_cache.settings')->get('expire_period') ?: SESSION_CACHE_DEFAULT_EXPIRATION_DAYS;
-  return REQUEST_TIME + 24*60*60 * $expire_period_days;
-}
-
 /**
- * Implements hook_menu().
+ * Returns the date/time that the session cache will expire.
+ *
+ * @return int
+ *   UNIX time stamp
  */
-function session_cache_menu() {
-  $items['admin/config/development/session-cache'] = array(
-    'title' => 'Session Cache API',
-    'description' => 'Select the session cache storage mechanism.',
-    'route_name' => 'session_cache_settings',
-  );
-  return $items;
+function session_cache_expiration_time() {
+  $expire_period_days = \Drupal::config('session_cache.settings')->get('expire_period') ?: SESSION_CACHE_DEFAULT_EXPIRATION_DAYS;
+  return REQUEST_TIME + 24*60*60 * $expire_period_days;
 }
diff --git a/session_cache.routing.yml b/session_cache.routing.yml
index 86c9e07..d726f1f 100644
--- a/session_cache.routing.yml
+++ b/session_cache.routing.yml
@@ -1,6 +1,7 @@
-session_cache_settings:
-  pattern: '/admin/config/development/session-cache'
+session_cache.admin_config:
+  path: /admin/config/development/session_cache
   defaults:
-    _form: '\Drupal\session_cache\Form\SessionCacheSettingsForm'
+    _title: 'Session Cache API'
+    _form: \Drupal\session_cache\Form\SessionCacheAdminConfig
   requirements:
-    _permission: 'administer site configuration'
\ No newline at end of file
+    _permission: 'administer site configuration'
diff --git a/session_cache_file/session_cache_file.info.yml b/session_cache_file/session_cache_file.info.yml
index e64e9f7..a962dd5 100644
--- a/session_cache_file/session_cache_file.info.yml
+++ b/session_cache_file/session_cache_file.info.yml
@@ -1,9 +1,7 @@
-name: Session Cache File
-type: module
-description: Extends Session Cache API with a file storage implementation.
-version: VERSION
-core: 8.x
+name: 'Session Cache File'
+description: 'Extends the Session Cache API with a file storage implementation.'
 dependencies:
   - session_cache
-configure: admin/config/development/session-cache
-
+core: 8.x
+project: session_cache
+type: module
diff --git a/session_cache_file/session_cache_file.install b/session_cache_file/session_cache_file.install
index adfdd22..44e9ff6 100644
--- a/session_cache_file/session_cache_file.install
+++ b/session_cache_file/session_cache_file.install
@@ -6,6 +6,27 @@
  */
 
 /**
+ * Implements hook_requirements().
+ */
+function session_cache_file_requirements($phase) {
+  if ($phase != 'runtime') {
+    return;
+  }
+  $t = 't';
+  $requirements['session_cache_file']['title'] = $t('Session Cache File cache');
+  $session_cache_root = session_cache_file_directory();
+  if ($session_cache_root) {
+    $requirements['session_cache_file']['value'] = $t('Installed at %path', array('%path' => $session_cache_root));
+    $requirements['session_cache_file']['severity'] = REQUIREMENT_OK;
+  }
+  else {
+    $requirements['session_cache_file']['value'] = $t('Not set or could not be created. Check directory permissions or re-configure <a href="@url">here</a>.', array('@url' => \Drupal\Core\Url::fromRoute('system.file_system_settings')));
+    $requirements['session_cache_file']['severity'] = REQUIREMENT_ERROR;
+  }
+  return $requirements;
+}
+
+/**
  * Implements hook_uninstall().
  */
 function session_cache_file_uninstall() {
@@ -19,26 +40,26 @@ function session_cache_file_uninstall() {
 
 /**
  * Recursively delete a directory and all files in it.
- * 
- * PHP's rmdir() only deletes if the directory is empty so we empty directories
- * recursively before calling rmdir().
+ *
+ * PHP's rmdir() only deletes if the directory is empty.
  *
  * @param string $dir
+ *   The directory to be removed with all its contents.
  */
 function session_cache_file_rrmdir($dir) {
- if (is_dir($dir)) {
-   $files = scandir($dir);
-   foreach ($files as $file) {
-     if ($file != '.' && $file != '..') {
-       if (is_dir("$dir/$file")) {
-         session_cache_file_rrmdir("$dir/$file");
-       }
-       else {
-         unlink("$dir/$file");
-       }
-     }
-   }
-   return rmdir($dir);
- }
- return FALSE;
+  if (is_dir($dir)) {
+    $files = scandir($dir);
+    foreach ($files as $file) {
+      if ($file != '.' && $file != '..') {
+        if (is_dir("$dir/$file")) {
+          session_cache_file_rrmdir("$dir/$file");
+        }
+        else {
+          unlink("$dir/$file");
+        }
+      }
+    }
+    return rmdir($dir);
+  }
+  return FALSE;
 }
diff --git a/session_cache_file/session_cache_file.module b/session_cache_file/session_cache_file.module
index 05f9f45..af14aa6 100644
--- a/session_cache_file/session_cache_file.module
+++ b/session_cache_file/session_cache_file.module
@@ -11,24 +11,39 @@
  * See the session_cache/README.txt for more info.
  */
 
-const SESSION_CACHE_STORAGE_FILE = 5;
+define('SESSION_CACHE_FILE_STORAGE_FILE', 5);
 
-/*
- * Implements hook_form_FORMID_alter().
+/**
+ * Implements hook_form_FORM_ID_alter().
  */
-function session_cache_file_form_session_cache_settings_alter(&$form, &$form_state) {
-  $form['storage_method']['#options'][SESSION_CACHE_STORAGE_FILE] =
-    t('on the server, as a small file');
+function session_cache_file_form_session_cache_admin_config_alter(&$form, &$form_state) {
+  $form['session_cache_storage_method']['#options'][SESSION_CACHE_FILE_STORAGE_FILE]
+    = t('on the server, as a small file');
 }
 
+/**
+ * Returns the directory path to where session cache files are stored.
+ *
+ * @param string $bin
+ *   The bin for which the path is to be returned, NULL for the base path.
+ *
+ * @return boolean|string
+ *   The existing or newly created path, or FALSE if there was an error.
+ */
 function session_cache_file_directory($bin = NULL) {
-  $path = config('system.file')->get('path.private');  // typically: sites/default/files/private
+  $path = \Drupal\Core\StreamWrapper\PrivateStream::basePath();
+
+  // Typically $path == 'sites/default/files/private'.
   if (empty($path)) {
     drupal_set_message(t('Session Cache File: the <strong>Private file system path</strong> is not set. Please configure it <a href="@url">here</a>.',
-      array('@url' => url('admin/config/media/file-system'))), 'warning', FALSE);
+      array('@url' => \Drupal\Core\Url::fromRoute('system.file_system_settings'))), 'warning', FALSE);
     return FALSE;
   }
-  $path = DRUPAL_ROOT . "/$path/session_cache";
+  // Use the absolute path as is, if it starts with a slash.
+  $path = preg_match('/^\//', $path) ? $path : \Drupal::root() . "/$path";
+  $path .= '/session_cache';
+
+  // @todo Use file_prepare_directory(&$path, FILE_CREATE_DIRECTORY)
   if (!file_exists($path) && !@mkdir($path)) {
     drupal_set_message(t('Session cache directory %path could not be created.',
       array('%path' => $path)), 'error', FALSE);
@@ -49,7 +64,7 @@ function session_cache_file_directory($bin = NULL) {
  * Implements hook_session_cache_set().
  */
 function session_cache_file_session_cache_set($method, $bin, $data) {
-  if ($method != SESSION_CACHE_STORAGE_FILE) {
+  if ($method != SESSION_CACHE_FILE_STORAGE_FILE) {
     return;
   }
   $path = session_cache_file_directory($bin);
@@ -68,14 +83,12 @@ function session_cache_file_session_cache_set($method, $bin, $data) {
  * Implements hook_session_cache_get().
  */
 function session_cache_file_session_cache_get($method, $bin) {
-  if ($method != SESSION_CACHE_STORAGE_FILE) {
+  if ($method != SESSION_CACHE_FILE_STORAGE_FILE) {
     return NULL;
   }
   $path = session_cache_file_directory($bin);
   $sid = session_cache_get_sid();
-  $data = $path && $sid && file_exists("$path/$sid")
-    ? unserialize(file_get_contents("$path/$sid"))
-    : NULL;
+  $data = $path && $sid && file_exists("$path/$sid") ? unserialize(file_get_contents("$path/$sid")) : NULL;
   return $data;
 }
 
@@ -95,7 +108,7 @@ function session_cache_file_cron() {
             if (strpos($filename, '.') !== 0) {
               $filespec = "$session_cache_root/$bin_dir/$filename";
               $last_modified = filemtime($filespec);
-              if ($last_modified && (time() - $last_modified > SESSION_CACHE_DEFAULT_EXPIRATION_DAYS *24*60*60)) {
+              if ($last_modified && (time() - $last_modified > SESSION_CACHE_DEFAULT_EXPIRATION_DAYS * 24 * 60 * 60)) {
                 if (!@unlink($filespec)) {
                   drupal_set_message(t('Could not delete expired session cache file %file.', array('%file' => $filespec)), 'warning');
                 }
@@ -107,23 +120,3 @@ function session_cache_file_cron() {
     }
   }
 }
-
-/**
- * Implements hook_requirements().
- */
-function session_cache_file_requirements($phase) {
-  if ($phase != 'runtime') {
-    return;
-  }
-  $requirements['session_cache_file']['title'] = t('Session Cache File cache');
-  $session_cache_root = session_cache_file_directory();
-  if ($session_cache_root) {
-    $requirements['session_cache_file']['value'] = t('Installed at %path', array('%path' => $session_cache_root));
-    $requirements['session_cache_file']['severity'] = REQUIREMENT_OK;
-  }
-  else {
-    $requirements['session_cache_file']['value'] = t('Not set or could not be created. Check directory permissions or re-configure <a href="@url">here</a>.', array('@url' => url('admin/config/media/file-system')));
-    $requirements['session_cache_file']['severity'] = REQUIREMENT_ERROR;
-  }
-  return $requirements;
-}
diff --git a/src/Form/SessionCacheAdminConfig.php b/src/Form/SessionCacheAdminConfig.php
new file mode 100644
index 0000000..e07f3de
--- /dev/null
+++ b/src/Form/SessionCacheAdminConfig.php
@@ -0,0 +1,90 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\session_cache\Form\SessionCacheAdminConfig.
+ */
+
+namespace Drupal\session_cache\Form;
+
+use Drupal\Core\Form\ConfigFormBase;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Render\Element;
+
+class SessionCacheAdminConfig extends ConfigFormBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormId() {
+    return 'session_cache_admin_config';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, FormStateInterface $form_state) {
+    $config = $this->config('session_cache.settings');
+
+    foreach (Element::children($form) as $variable) {
+      $config->set($variable, $form_state->getValue($form[$variable]['#parents']));
+    }
+    $config->save();
+
+    if (method_exists($this, '_submitForm')) {
+      $this->_submitForm($form, $form_state);
+    }
+
+    parent::submitForm($form, $form_state);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getEditableConfigNames() {
+    return ['session_cache.settings'];
+  }
+
+  public function buildForm(array $form, \Drupal\Core\Form\FormStateInterface $form_state) {
+    $form['storage_method'] = [
+      '#type' => 'radios',
+      '#title' => t('Where should user session data be stored?'),
+      '#default_value' => \Drupal::config('session_cache.settings')->get('storage_method'),
+      '#options' => [
+        SESSION_CACHE_STORAGE_COOKIE => t("on the user's computer, in a cookie"),
+        SESSION_CACHE_STORAGE_DB_CORE => t("on the server, on core's cache database"),
+        SESSION_CACHE_STORAGE_SESSION => t('on the server, in $_SESSION memory'),
+      ],
+      '#description' => t('When using Varnish or similar page caching engine for anonymous users, do not use $_SESSION and have a page exclusion strategy in place.'),
+    ];
+
+    $options = [
+      SESSION_CACHE_COOKIE_FOR_SID => t('via their cookie'),
+      SESSION_CACHE_UID_FOR_SID => t('via their login id, via cookie for anonymous users (works cross-browser for authenticated users)'),
+      SESSION_CACHE_IP_ADDRESS_FOR_SID => t('via their IP address'),
+    ];
+    $form['sid_source'] = [
+      '#type' => 'radios',
+      '#title' => t('Method for identifying the user in database and file-based storage methods'),
+      '#options' => $options,
+      '#default_value' => \Drupal::config('session_cache.settings')->get('sid_source'),
+      '#description' => t('None of the above apply to the $_SESSION and cookie storage mechanisms.'),
+    ];
+
+    $expire_period = (float) \Drupal::config('session_cache.settings')->get('expire_period');
+    if ($expire_period <= 0.0) {
+      $expire_period = SESSION_CACHE_DEFAULT_EXPIRATION_DAYS;
+    }
+    $form['expire_period'] = [
+      '#type' => 'textfield',
+      '#size' => 4,
+      '#title' => t('Expiration time for the database cache and cookies created via this module'),
+      '#field_suffix' => t('days'),
+      '#default_value' => $expire_period,
+      '#description' => t('You may use decimals, eg 0.25 equates to 6 hours.<br/>$_SESSION expiration is set via the server configuration. See the <em>sites/default/settings.php</em> file for details.'),
+    ];
+
+    return parent::buildForm($form, $form_state);
+  }
+
+}
