laravelでのsession
laravelではセッションの起点が\Illuminate\Session\Middleware\StartSession
というミドルウェアになります。
public function handle($request, Closure $next)
{
if (! $this->sessionConfigured()) {
return $next($request);
}
$request->setLaravelSession(
$session = $this->startSession($request)
);
$this->collectGarbage($session);
$response = $next($request);
$this->storeCurrentUrl($request, $session);
$this->addCookieToResponse($response, $session);
$this->saveSession($request);
return $response;
}
$this->sessionConfigured()
でセッションを開始するかどうかを判定しています。
laravelではセッションの設定はconfig/session
に記述していきます。そのファイルがなかったり、driverがnullだったりするとセッションは使われません。
sessionの開始
$request->setLaravelSession()
はリクエストのプロパティに生成したセッションをセットしているだけなので、実質的な処理は$this->startSession
になります。
protected function startSession(Request $request)
{
return tap($this->getSession($request), function ($session) use ($request) {
$session->setRequestOnHandler($request);
$session->start();
});
}
sessionの取得
$this->getSession()
でセッションの取得を行っていきます。
public function getSession(Request $request)
{
return tap($this->manager->driver(), function ($session) use ($request) {
$session->setId($request->cookies->get($session->getName()));
});
}
/Illuminate/Session/SessionManager
のdriver()
を呼んでドライバーの取得をしています。driver()
自体はスーパークラスの/Illuminate/Support/Manager
に実装されており、最終的にSessionManager::createNativeDriver
が呼ばれます。
ドライバーとはセッションの値をどこに保存するかを決めるもので、デフォルトではfileになっていて、databaseなどにも変更できるようです。
protected function createNativeDriver()
{
$lifetime = $this->config->get('session.lifetime');
return $this->buildSession(new FileSessionHandler(
$this->container->make('files'), $this->config->get('session.files'), $lifetime
));
}
$this->buildSession()
にセッション用のファイルハンドラを渡してセッションを生成してそうです。
protected function buildSession($handler)
{
return $this->config->get('session.encrypt')
? $this->buildEncryptedSession($handler)
: new Store($this->config->get('session.cookie'), $handler);
}
$this->config->get('session.encrypt')
はデフォルトではfalseなので、ここで本体である/Illuminate/Session/Store
が生成されています。
ここで第一引数に渡している文字列はcookieのNameとして使われています。(APP_NAME_session)ブラウザでも確認することができますね!
セッションIDのセット
セッションをのインスタンスを取得したので、getSession()
に戻って、tap関数でidをセットしていきます。
$session->setId($request->cookies->get($session->getName()));
先程new Store()
の第一引数に渡した文字列を使って、cookieからidを取得しています。もしidがなければidを生成してセットしてくれます。
セッションの開始
無事にセッションを取得できたので、セッションを開始してきます。
($session->setRequestOnHandler($request)
はデフォルトでは関係ないので割愛)
protected function startSession(Request $request)
{
return tap($this->getSession($request), function ($session) use ($request) {
$session->setRequestOnHandler($request);
$session->start();
});
}
public function start()
{
$this->loadSession();
if (! $this->has('_token')) {
$this->regenerateToken();
}
return $this->started = true;
}
loadSession()
でfileからセッションに格納している値を読み出してきます。
その中に_token
(CSRF用)がなければトークンを生成します。
以上でセッションを利用する準備が整いました!