annotate core/lib/Drupal/Core/Session/SessionConfiguration.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 129ea1e6d783
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\Core\Session;
Chris@0 4
Chris@0 5 use Symfony\Component\HttpFoundation\Request;
Chris@0 6
Chris@0 7 /**
Chris@0 8 * Defines the default session configuration generator.
Chris@0 9 */
Chris@0 10 class SessionConfiguration implements SessionConfigurationInterface {
Chris@0 11
Chris@0 12 /**
Chris@0 13 * An associative array of session ini settings.
Chris@0 14 */
Chris@0 15 protected $options;
Chris@0 16
Chris@0 17 /**
Chris@0 18 * Constructs a new session configuration instance.
Chris@0 19 *
Chris@0 20 * @param array $options
Chris@0 21 * An associative array of session ini settings.
Chris@0 22 *
Chris@0 23 * @see \Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage::__construct()
Chris@0 24 * @see http://php.net/manual/session.configuration.php
Chris@0 25 */
Chris@0 26 public function __construct($options = []) {
Chris@0 27 $this->options = $options;
Chris@0 28 }
Chris@0 29
Chris@0 30 /**
Chris@0 31 * {@inheritdoc}
Chris@0 32 */
Chris@0 33 public function hasSession(Request $request) {
Chris@0 34 return $request->cookies->has($this->getName($request));
Chris@0 35 }
Chris@0 36
Chris@0 37 /**
Chris@0 38 * {@inheritdoc}
Chris@0 39 */
Chris@0 40 public function getOptions(Request $request) {
Chris@0 41 $options = $this->options;
Chris@0 42
Chris@0 43 // Generate / validate the cookie domain.
Chris@0 44 $options['cookie_domain'] = $this->getCookieDomain($request) ?: '';
Chris@0 45
Chris@0 46 // If the site is accessed via SSL, ensure that the session cookie is
Chris@0 47 // issued with the secure flag.
Chris@0 48 $options['cookie_secure'] = $request->isSecure();
Chris@0 49
Chris@0 50 // Set the session cookie name.
Chris@0 51 $options['name'] = $this->getName($request);
Chris@0 52
Chris@0 53 return $options;
Chris@0 54 }
Chris@0 55
Chris@0 56 /**
Chris@0 57 * Returns the session cookie name.
Chris@0 58 *
Chris@0 59 * @param \Symfony\Component\HttpFoundation\Request $request
Chris@0 60 * The request.
Chris@0 61 *
Chris@0 62 * @return string
Chris@0 63 * The name of the session cookie.
Chris@0 64 */
Chris@0 65 protected function getName(Request $request) {
Chris@0 66 // To prevent session cookies from being hijacked, a user can configure the
Chris@0 67 // SSL version of their website to only transfer session cookies via SSL by
Chris@0 68 // using PHP's session.cookie_secure setting. The browser will then use two
Chris@0 69 // separate session cookies for the HTTPS and HTTP versions of the site. So
Chris@0 70 // we must use different session identifiers for HTTPS and HTTP to prevent a
Chris@0 71 // cookie collision.
Chris@0 72 $prefix = $request->isSecure() ? 'SSESS' : 'SESS';
Chris@0 73 return $prefix . $this->getUnprefixedName($request);
Chris@0 74 }
Chris@0 75
Chris@0 76 /**
Chris@0 77 * Returns the session cookie name without the secure/insecure prefix.
Chris@0 78 *
Chris@0 79 * @param \Symfony\Component\HttpFoundation\Request $request
Chris@0 80 * The request.
Chris@0 81 *
Chris@0 82 * @returns string
Chris@0 83 * The session name without the prefix (SESS/SSESS).
Chris@0 84 */
Chris@0 85 protected function getUnprefixedName(Request $request) {
Chris@0 86 if ($test_prefix = $this->drupalValidTestUa()) {
Chris@0 87 $session_name = $test_prefix;
Chris@0 88 }
Chris@0 89 elseif (isset($this->options['cookie_domain'])) {
Chris@0 90 // If the user specifies the cookie domain, also use it for session name.
Chris@0 91 $session_name = $this->options['cookie_domain'];
Chris@0 92 }
Chris@0 93 else {
Chris@0 94 // Otherwise use $base_url as session name, without the protocol
Chris@0 95 // to use the same session identifiers across HTTP and HTTPS.
Chris@0 96 $session_name = $request->getHost() . $request->getBasePath();
Chris@0 97 // Replace "core" out of session_name so core scripts redirect properly,
Chris@0 98 // specifically install.php.
Chris@0 99 $session_name = preg_replace('#/core$#', '', $session_name);
Chris@0 100 }
Chris@0 101
Chris@0 102 return substr(hash('sha256', $session_name), 0, 32);
Chris@0 103 }
Chris@0 104
Chris@0 105 /**
Chris@0 106 * Return the session cookie domain.
Chris@0 107 *
Chris@0 108 * The Set-Cookie response header and its domain attribute are defined in RFC
Chris@17 109 * 2109, RFC 2965 and RFC 6265 each one superseding the previous version.
Chris@0 110 *
Chris@0 111 * @see http://tools.ietf.org/html/rfc2109
Chris@0 112 * @see http://tools.ietf.org/html/rfc2965
Chris@0 113 * @see http://tools.ietf.org/html/rfc6265
Chris@0 114 *
Chris@0 115 * @param \Symfony\Component\HttpFoundation\Request $request
Chris@0 116 * The request.
Chris@0 117 *
Chris@0 118 * @returns string
Chris@0 119 * The session cookie domain.
Chris@0 120 */
Chris@0 121 protected function getCookieDomain(Request $request) {
Chris@0 122 if (isset($this->options['cookie_domain'])) {
Chris@0 123 $cookie_domain = $this->options['cookie_domain'];
Chris@0 124 }
Chris@0 125 else {
Chris@0 126 $host = $request->getHost();
Chris@0 127 // To maximize compatibility and normalize the behavior across user
Chris@0 128 // agents, the cookie domain should start with a dot.
Chris@0 129 $cookie_domain = '.' . $host;
Chris@0 130 }
Chris@0 131
Chris@0 132 // Cookies for domains without an embedded dot will be rejected by user
Chris@0 133 // agents in order to defeat malicious websites attempting to set cookies
Chris@0 134 // for top-level domains. Also IP addresses may not be used in the domain
Chris@0 135 // attribute of a Set-Cookie header.
Chris@0 136 if (count(explode('.', $cookie_domain)) > 2 && !is_numeric(str_replace('.', '', $cookie_domain))) {
Chris@0 137 return $cookie_domain;
Chris@0 138 }
Chris@0 139 }
Chris@0 140
Chris@0 141 /**
Chris@0 142 * Wraps drupal_valid_test_ua().
Chris@0 143 *
Chris@0 144 * @return string|false
Chris@0 145 * Either the simpletest prefix (the string "simpletest" followed by any
Chris@0 146 * number of digits) or FALSE if the user agent does not contain a valid
Chris@0 147 * HMAC and timestamp.
Chris@0 148 */
Chris@0 149 protected function drupalValidTestUa() {
Chris@0 150 return drupal_valid_test_ua();
Chris@0 151 }
Chris@0 152
Chris@0 153 }