参考把session存到redis
一。配置
1.config->session.php
'driver' => env('SESSION_DRIVER', 'file')//存储session驱动,
//支持"file", "cookie", "database", "apc","memcached", "redis", "array"
其它自己看,框架有英文注释
2.如果是选redis驱动,配置文件config->database.php
'redis' => [
'cluster' => false,
'default' => [
'host' => $redis_ip,
'password' => env('REDIS_PASSWORD', '3EDC2WSX1QAZ'),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
],
'cache' => [
'host' => $redis_ip,
'password' => env('REDIS_PASSWORD', '3EDC2WSX1QAZ'),
'port' => env('REDIS_PORT', 6379),
'database' => 1,
],
'session' => [//session,存储信息
'host' => $redis_ip,
'password' => env('REDIS_PASSWORD', '3EDC2WSX1QAZ'),
'port' => env('REDIS_PORT', 6379),
'database' => 2,//redis数据库;redis-cli客户端用select 2,可查看
],
二。查看中间件app->Http->Kernel.php
'ncompass\\Http\\Middleware\\EncryptCookies',//解码cookie,得到sessionID。
'Illuminate\\Session\\Middleware\\StartSession',//存session的中间件
三。打开EncryptCookies这个类,继承了EncryptCookies.查看handle函数,下面是得到请求的cookie把cookie解码,得到sessionID
public function handle($request, Closure $next)
{
//把请求解码
return $this->encrypt($next($this->decrypt($request)));
}
protected function decrypt(Request $request)
{
foreach ($request->cookies as $key => $c) {
if ($this->isDisabled($key)) {
continue;
}
try { //解码cookie
$request->cookies->set($key, $this->decryptCookie($c));
} catch (DecryptException $e) {
$request->cookies->set($key, null);
}
}
return $request;
}
protected function decryptCookie($cookie)
{
return is_array($cookie)
? $this->decryptArray($cookie)
: $this->encrypter->decrypt($cookie);//调用了
}
public function decrypt($payload)
{
$payload = $this->getJsonPayload($payload);//这里返回的数组
$iv = base64_decode($payload['iv']);
$decrypted = \openssl_decrypt($payload['value'], $this->cipher, $this->key, 0, $iv);
if ($decrypted === false) {
throw new DecryptException('Could not decrypt the data.');
}
//返回sessionID;*********
return unserialize($decrypted);
}
protected function getJsonPayload($payload)
{
//把cookie反base64编码,再变成json
$payload = json_decode(base64_decode($payload), true);
// If the payload is not valid JSON or does not have the proper keys set we will
// assume it is invalid and bail out of the routine since we will not be able
// to decrypt the given value. We'll also check the MAC for this encryption.
if (! $payload || $this->invalidPayload($payload)) {
throw new DecryptException('The payload is invalid.');
}
if (! $this->validMac($payload)) {
throw new DecryptException('The MAC is invalid.');
}
return $payload;
}
四。打开StartSession这个类,可看到Handle这个函数。主要这个函数$this->startSession($request)。把cookie里的sessionid拿出来去redis里找到数据,就可以得到用户的数据了。
public function handle($request, Closure $next)
{
$this->sessionHandled = true;
// If a session driver has been configured, we will need to start the session here
// so that the data is ready for an application. Note that the Laravel sessions
// do not make use of PHP "native" sessions in any way since they are crappy.
if ($this->sessionConfigured()) {
//把请求$request相关的cookie存到sesion里
$session = $this->startSession($request);
$request->setSession($session);
}
$response = $next($request);
// Again, if the session has been configured we will need to close out the session
// so that the attributes may be persisted to some storage medium. We will also
// add the session identifier cookie to the application response headers now.
if ($this->sessionConfigured()) {
$this->storeCurrentUrl($request, $session);
$this->collectGarbage($session);
$this->addCookieToResponse($response, $session);//设置响应cookie
}
return $response;
}
五。查看startSession()这个函数,看注释,最终是redis的cache
protected function startSession(Request $request)
{
with($session = $this->getSession($request))->setRequestOnHandler($request);
//以下会解释$session为Illuminate\Session\Store的对象
//经过start()函数会加上token等,store.php里的loadsession()函数会通过sessionid读用户数据的
$session->start();
return $session;
}
//$this->manager是\Illuminate\Session\SessionManager的对象
public function getSession(Request $request)
{
//driver()是sessionManager类继承了Manager里的driver()
$session = $this->manager->driver();
$session->setId($request->cookies->get($session->getName()));
return $session;
}
public function driver($driver = null)
{
//调用SessionManager自己的getDefaultDriver()函数,返回redis字符串
$driver = $driver ?: $this->getDefaultDriver();
// If the given driver has not been created before, we will create the instances
// here and cache it so we can return it next time very quickly. If there is
// already a driver created by this name, we'll just return that instance.
if (! isset($this->drivers[$driver])) {
//创建驱动
$this->drivers[$driver] = $this->createDriver($driver);
}
return $this->drivers[$driver];
}
protected function createDriver($driver)
{
$method = 'create' . ucfirst($driver) . 'Driver';
// We'll check to see if a creator method exists for the given driver. If not we
// will check for a custom driver creator, which allows developers to create
// drivers using their own customized driver creator Closure to create it.
if (isset($this->customCreators[$driver])) {
return $this->callCustomCreator($driver);
} elseif (method_exists($this, $method)) {
//$method为createRedisDriver字符串
return $this->$method();//调用sessionManager自己的createRedisDriver函数
}
throw new InvalidArgumentException("Driver [$driver] not supported.");
}
protected function createRedisDriver()
{
//创建一个redis的cache,带过期时间等
$handler = $this->createCacheHandler('redis');
//链接存储数据库
$handler->getCache()->getStore()->setConnection($this->app['config']['session.connection']);
//存储加密的数据到session
return $this->buildSession($handler);
}
protected function buildSession($handler)
{
if ($this->app['config']['session.encrypt']) {
return new EncryptedStore(
$this->app['config']['session.cookie'],
$handler,
$this->app['encrypter']
);
} else {
//最终返回startSession函数里的$session为new Illuminate\Session\Store()的对象
return new Store($this->app['config']['session.cookie'], $handler);
}
}