laravel5的session存储过程

参考把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);
        }
    }

    

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值