EncryptCookies.php
TLDR
This file EncryptCookies.php
is a part of the Illuminate\Cookie\Middleware
namespace in the Laravel framework. It contains a class called EncryptCookies
which is responsible for encrypting and decrypting cookies in the application. The class handles the encryption and decryption of cookies, as well as disabling encryption for specific cookies.
Methods
__construct
This method is the constructor of the EncryptCookies
class. It accepts an instance of the EncrypterContract
interface and initializes the encrypter
property.
disableFor
This method is used to disable encryption for the given cookie name(s). It accepts a string or an array of cookie names and merges them with the except
property.
handle
This method is used to handle an incoming request. It accepts a Request
instance and a Closure
as parameters. It calls the decrypt
method to decrypt the cookies on the request, then passes the decrypted request through the $next
closure. Finally, it calls the encrypt
method to encrypt the cookies on the outgoing response.
decrypt
This method is used to decrypt the cookies on the request. It accepts a Request
instance and loops through each cookie on the request. If the cookie is not disabled (based on the isDisabled
method), it attempts to decrypt the cookie value using the encrypter
. If decryption fails, the cookie value is set to null
.
validateValue
This method is used to validate and remove the cookie value prefix from the value. It accepts a string $key
and a value, and returns the validated value. If the value is an array, it calls the validateArray
method.
validateArray
This method is used to validate and remove the cookie value prefix from all values of an array. It accepts a string $key
and an array $value
. It loops through each value in the array and recursively calls the validateValue
method to validate each value.
decryptCookie
This method is used to decrypt the given cookie and return the value. It accepts a string $name
and a value $cookie
. If the value is an array, it calls the decryptArray
method. Otherwise, it calls the decrypt
method of the encrypter
to perform the decryption.
decryptArray
This method is used to decrypt an array based cookie. It accepts an array $cookie
and decrypts each value recursively by calling the decrypt
method of the encrypter
.
encrypt
This method is used to encrypt the cookies on an outgoing response. It accepts a Response
instance and loops through each cookie in the response headers. If the cookie is not disabled, it encrypts the cookie value by prepending a value prefix and encrypting the entire value using the encrypter
. It sets the encrypted cookie on the response headers using the duplicate
method.
duplicate
This method is used to duplicate a cookie with a new value. It accepts a Cookie
instance and a new value and returns a new Cookie
instance with the updated value.
isDisabled
This method is used to determine whether encryption has been disabled for the given cookie. It accepts a string $name
and checks if the cookie name is present in the except
property or the static::$neverEncrypt
property.
except
This method is used to indicate that the given cookies should never be encrypted. It accepts an array or a string of cookie names and merges them with the static::$neverEncrypt
property.
serialized
This method is used to determine if the cookie contents should be serialized. It accepts a string $name
and returns the value of the static::$serialize
property.
Classes
There are no additional classes in the file.
<?php
namespace Illuminate\Cookie\Middleware;
use Closure;
use Illuminate\Contracts\Encryption\DecryptException;
use Illuminate\Contracts\Encryption\Encrypter as EncrypterContract;
use Illuminate\Cookie\CookieValuePrefix;
use Illuminate\Support\Arr;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class EncryptCookies
{
/**
* The encrypter instance.
*
* @var \Illuminate\Contracts\Encryption\Encrypter
*/
protected $encrypter;
/**
* The names of the cookies that should not be encrypted.
*
* @var array<int, string>
*/
protected $except = [];
/**
* The globally ignored cookies that should not be encrypted.
*
* @var array
*/
protected static $neverEncrypt = [];
/**
* Indicates if cookies should be serialized.
*
* @var bool
*/
protected static $serialize = false;
/**
* Create a new CookieGuard instance.
*
* @param \Illuminate\Contracts\Encryption\Encrypter $encrypter
* @return void
*/
public function __construct(EncrypterContract $encrypter)
{
$this->encrypter = $encrypter;
}
/**
* Disable encryption for the given cookie name(s).
*
* @param string|array $name
* @return void
*/
public function disableFor($name)
{
$this->except = array_merge($this->except, (array) $name);
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return \Symfony\Component\HttpFoundation\Response
*/
public function handle($request, Closure $next)
{
return $this->encrypt($next($this->decrypt($request)));
}
/**
* Decrypt the cookies on the request.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* @return \Symfony\Component\HttpFoundation\Request
*/
protected function decrypt(Request $request)
{
foreach ($request->cookies as $key => $cookie) {
if ($this->isDisabled($key)) {
continue;
}
try {
$value = $this->decryptCookie($key, $cookie);
$request->cookies->set($key, $this->validateValue($key, $value));
} catch (DecryptException) {
$request->cookies->set($key, null);
}
}
return $request;
}
/**
* Validate and remove the cookie value prefix from the value.
*
* @param string $key
* @param string $value
* @return string|array|null
*/
protected function validateValue(string $key, $value)
{
return is_array($value)
? $this->validateArray($key, $value)
: CookieValuePrefix::validate($key, $value, $this->encrypter->getKey());
}
/**
* Validate and remove the cookie value prefix from all values of an array.
*
* @param string $key
* @param array $value
* @return array
*/
protected function validateArray(string $key, array $value)
{
$validated = [];
foreach ($value as $index => $subValue) {
$validated[$index] = $this->validateValue("{$key}[{$index}]", $subValue);
}
return $validated;
}
/**
* Decrypt the given cookie and return the value.
*
* @param string $name
* @param string|array $cookie
* @return string|array
*/
protected function decryptCookie($name, $cookie)
{
return is_array($cookie)
? $this->decryptArray($cookie)
: $this->encrypter->decrypt($cookie, static::serialized($name));
}
/**
* Decrypt an array based cookie.
*
* @param array $cookie
* @return array
*/
protected function decryptArray(array $cookie)
{
$decrypted = [];
foreach ($cookie as $key => $value) {
if (is_string($value)) {
$decrypted[$key] = $this->encrypter->decrypt($value, static::serialized($key));
}
if (is_array($value)) {
$decrypted[$key] = $this->decryptArray($value);
}
}
return $decrypted;
}
/**
* Encrypt the cookies on an outgoing response.
*
* @param \Symfony\Component\HttpFoundation\Response $response
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function encrypt(Response $response)
{
foreach ($response->headers->getCookies() as $cookie) {
if ($this->isDisabled($cookie->getName())) {
continue;
}
$response->headers->setCookie($this->duplicate(
$cookie,
$this->encrypter->encrypt(
CookieValuePrefix::create($cookie->getName(), $this->encrypter->getKey()).$cookie->getValue(),
static::serialized($cookie->getName())
)
));
}
return $response;
}
/**
* Duplicate a cookie with a new value.
*
* @param \Symfony\Component\HttpFoundation\Cookie $cookie
* @param mixed $value
* @return \Symfony\Component\HttpFoundation\Cookie
*/
protected function duplicate(Cookie $cookie, $value)
{
return $cookie->withValue($value);
}
/**
* Determine whether encryption has been disabled for the given cookie.
*
* @param string $name
* @return bool
*/
public function isDisabled($name)
{
return in_array($name, array_merge($this->except, static::$neverEncrypt));
}
/**
* Indicate that the given cookies should never be encrypted.
*
* @param array|string $cookies
* @return void
*/
public static function except($cookies)
{
static::$neverEncrypt = array_values(array_unique(
array_merge(static::$neverEncrypt, Arr::wrap($cookies))
));
}
/**
* Determine if the cookie contents should be serialized.
*
* @param string $name
* @return bool
*/
public static function serialized($name)
{
return static::$serialize;
}
}