3 namespace Drupal\Core\Session;
5 use Symfony\Component\HttpFoundation\Request;
8 * Defines the default session configuration generator.
10 class SessionConfiguration implements SessionConfigurationInterface {
13 * An associative array of session ini settings.
18 * Constructs a new session configuration instance.
20 * @param array $options
21 * An associative array of session ini settings.
23 * @see \Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage::__construct()
24 * @see http://php.net/manual/session.configuration.php
26 public function __construct($options = []) {
27 $this->options = $options;
33 public function hasSession(Request $request) {
34 return $request->cookies->has($this->getName($request));
40 public function getOptions(Request $request) {
41 $options = $this->options;
43 // Generate / validate the cookie domain.
44 $options['cookie_domain'] = $this->getCookieDomain($request) ?: '';
46 // If the site is accessed via SSL, ensure that the session cookie is
47 // issued with the secure flag.
48 $options['cookie_secure'] = $request->isSecure();
50 // Set the session cookie name.
51 $options['name'] = $this->getName($request);
57 * Returns the session cookie name.
59 * @param \Symfony\Component\HttpFoundation\Request $request
63 * The name of the session cookie.
65 protected function getName(Request $request) {
66 // To prevent session cookies from being hijacked, a user can configure the
67 // SSL version of their website to only transfer session cookies via SSL by
68 // using PHP's session.cookie_secure setting. The browser will then use two
69 // separate session cookies for the HTTPS and HTTP versions of the site. So
70 // we must use different session identifiers for HTTPS and HTTP to prevent a
72 $prefix = $request->isSecure() ? 'SSESS' : 'SESS';
73 return $prefix . $this->getUnprefixedName($request);
77 * Returns the session cookie name without the secure/insecure prefix.
79 * @param \Symfony\Component\HttpFoundation\Request $request
83 * The session name without the prefix (SESS/SSESS).
85 protected function getUnprefixedName(Request $request) {
86 if ($test_prefix = $this->drupalValidTestUa()) {
87 $session_name = $test_prefix;
89 elseif (isset($this->options['cookie_domain'])) {
90 // If the user specifies the cookie domain, also use it for session name.
91 $session_name = $this->options['cookie_domain'];
94 // Otherwise use $base_url as session name, without the protocol
95 // to use the same session identifiers across HTTP and HTTPS.
96 $session_name = $request->getHost() . $request->getBasePath();
97 // Replace "core" out of session_name so core scripts redirect properly,
98 // specifically install.php.
99 $session_name = preg_replace('#/core$#', '', $session_name);
102 return substr(hash('sha256', $session_name), 0, 32);
106 * Return the session cookie domain.
108 * The Set-Cookie response header and its domain attribute are defined in RFC
109 * 2109, RFC 2965 and RFC 6265 each one superseeding the previous version.
111 * @see http://tools.ietf.org/html/rfc2109
112 * @see http://tools.ietf.org/html/rfc2965
113 * @see http://tools.ietf.org/html/rfc6265
115 * @param \Symfony\Component\HttpFoundation\Request $request
119 * The session cookie domain.
121 protected function getCookieDomain(Request $request) {
122 if (isset($this->options['cookie_domain'])) {
123 $cookie_domain = $this->options['cookie_domain'];
126 $host = $request->getHost();
127 // To maximize compatibility and normalize the behavior across user
128 // agents, the cookie domain should start with a dot.
129 $cookie_domain = '.' . $host;
132 // Cookies for domains without an embedded dot will be rejected by user
133 // agents in order to defeat malicious websites attempting to set cookies
134 // for top-level domains. Also IP addresses may not be used in the domain
135 // attribute of a Set-Cookie header.
136 if (count(explode('.', $cookie_domain)) > 2 && !is_numeric(str_replace('.', '', $cookie_domain))) {
137 return $cookie_domain;
142 * Wraps drupal_valid_test_ua().
144 * @return string|false
145 * Either the simpletest prefix (the string "simpletest" followed by any
146 * number of digits) or FALSE if the user agent does not contain a valid
147 * HMAC and timestamp.
149 protected function drupalValidTestUa() {
150 return drupal_valid_test_ua();