0

小弟开发过程中遇到laravel上面不明白的地方,可能是最近才开始用这个框架的原因吧.
对于laravel session的问题还不是很了解,希望有研究laravel框架的朋友可以帮忙解答下我的疑问,
说下小弟开发项目的情况吧.

首先用了 laravel来建立了用户中心系统, 然后通过session保存在redis里面的办法与其他"应用",例如: 文章系统(也是laravel为框架开发)来进行用户的登录信息共享同步.

问题来了:

  1. 我发现两个laravel (5.1版本) 项目之间进行session的读写 (我并不清楚session的id是的生成机制跟逻辑) 生成的session跟app/config里面的文件有关. 两个项目随便改下app/config里面的配置文件都会引起session的用户信息无法读取成功.

  2. 因为公司的项目不是全部用laravel (起码短期内需要慢慢过渡)那假设, 有些项目使用TP或者CI等框架, 那这些框架要怎样才能成功获取laravel的session呢?

盼望高手指点,谢谢

j955 69
2015-09-21 提问
6 个回答
3

已采纳

好,我来了。
此处简单介绍Laravel的Session机制(现学现卖,感谢题主提供机会),以下都以不加密的file模式举例子。
Laravel是如何存储和读取的呢?
先说存储,
我们可以看\Illuminate\Session\SessionManager中的createNativeDriver中调用了FileSessionHandler类。
写入的位置在PATH\storage\framework\sessions目录下,以id作为文件名,这个id是从用户的cookie中读取的。
写入不介绍了,因为题主想读取,我这先简单介绍下如何读取File中Session的数据。

我们看\Illumiate\Session\Store中的loadSession方法,有一个调用$this->readFromHandler()

函数定义如下:

 protected function readFromHandler()
    {
        $data = $this->handler->read($this->getId());

        if ($data) {
            $data = @unserialize($this->prepareForUnserialize($data));

            if ($data !== false && $data !== null && is_array($data)) {
                return $data;
            }
        }

        return [];
    }

我们知道如果是File那么用的就是FileSessionHandler, 它的read非常简单

public function read($sessionId)
    {
        if ($this->files->exists($path = $this->path.'/'.$sessionId)) {
            return $this->files->get($path);
        }

        return '';
    }

就是从文件里读数据,完了。

所以实际情况,我们看我目录下面的序列化的session文件.

a:5:{s:6:"_token";s:40:"kHhZ458I4t5y2M3CMsAvLNrqy4GOOgCkRiRbhiD5";s:9:"_previous";a:1:{s:3:"url";s:16:"http://localhost";}s:5:"flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}s:38:"login_82e5d2c56bdd0811318f0cf078b78bfc";i:1;s:9:"_sf2_meta";a:3:{s:1:"u";i:1442888664;s:1:"c";i:1442887470;s:1:"l";s:1:"0";}}

尝试unserialize,得到结果。
clipboard.png

知道laravel存储的位置和算法的话,你沿着Handler的read方法,就可以读取到你自己的framework里了(当然需要做一个适配器进行转换)。

有问题欢迎交流~

1

好了 我找到了 php有个函数 debug_print_backtrace()
很好用。
\Illuminate\Cookie\Middleware\EncryptCookies这个类,里面有解密Cookie的
你看91行。

protected function decryptCookie($cookie)
    {
        return is_array($cookie)
                        ? $this->decryptArray($cookie)
                        : $this->encrypter->decrypt($cookie);
    }

这就是解密你那个串的,然后我通过打印$this->encrypter发现它是
Illuminate\Encryption\Encrypter这个类
调用

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.');
        }

        return unserialize($decrypted);
    }

这个方法,也就是说,你只要有$this->cipher, $this->key 这两个参数就能解密出你的cookie了。
然后看getJsonPayload

protected function getJsonPayload($payload)
    {
        $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;
    }

!!!找到你说的base64_decode用的地方了

Gemini · 2015年09月22日

展开评论
0

多应用共享为毛不用rest呢?

0

因为laravel的作者,觉得php系统的session一点不优雅,所以,另起炉灶自己搞了一个,
当然,是不兼容php原生session的,
如果真的要多项目共享的话(不仅仅是laravel),有两种方法,
一种就是为其他应用做一个laravel-session的兼容类,但是这个成本有点高.
另外一种,就是业务里面用到session的地方,弃用laravel session,
使用php原生session (session_start() 启动),
这样共享的数据所有php都看得懂了

0

不同系统统一登录应该自己设计一套规则和机制,其实和larval没什么关系

0

很简单,直接在入口文件写上session_start();

-1

使用oauth2.0

撰写答案

你可能感兴趣的

推广链接