【Laravel5】特定のCookieだけ暗号化を解除する
こんにちは、ナカエです。
先日、Laravel5.1での開発中に、
DBから読みだした値をCookieにセットしJavaScriptから利用する必要がありました。
本日の記事は、Cookieのキーによって暗号化の有無を変える方法についてです。
LaravelにはCookieの値を暗号化するHTTPミドルウェアとして、
\Illuminate\Cookie\Middleware\EncryptCookiesクラスが標準で用意されています。
このミドルウェアを有効にしていると、
HTTPリクエスト→EncryptCookiesでCookieの値を復号→アプリケーションでの処理→EncryptCookiesで暗号化→HTTPレスポンス
という流れで、アプリケーション内でCookieを設定した場合、
クライアント側には値が暗号化されたCookieが渡ることになります。
このままではJavaScriptで値を読み込んで利用することができません。
かといってEncryptCookiesミドルウェアそのものを無効にするという選択肢は取りたくない……。
そこで、一部のキーだけ暗号化させない方法を調べました。
EncryptCookiesクラスのコードを読んでみると、
protectedなプロパティである$exceptに登録されているキーは暗号化しないという処理になっています。
元のクラスを継承したクラスを用意し、
●app/Http/Middleware/EncryptCookies
利用するミドルウェアも差し替えます
●app/Http/Kernel.php
もうすこし詳しく見てみると
暗号化対象外のキーを外部から追加するためにEncryptCookies::disableFor()というpublicなメソッドが用意されていることがわかります。
先日、Laravel5.1での開発中に、
DBから読みだした値をCookieにセットしJavaScriptから利用する必要がありました。
本日の記事は、Cookieのキーによって暗号化の有無を変える方法についてです。
LaravelにはCookieの値を暗号化するHTTPミドルウェアとして、
\Illuminate\Cookie\Middleware\EncryptCookiesクラスが標準で用意されています。
このミドルウェアを有効にしていると、
HTTPリクエスト→EncryptCookiesでCookieの値を復号→アプリケーションでの処理→EncryptCookiesで暗号化→HTTPレスポンス
という流れで、アプリケーション内でCookieを設定した場合、
クライアント側には値が暗号化されたCookieが渡ることになります。
このままではJavaScriptで値を読み込んで利用することができません。
かといってEncryptCookiesミドルウェアそのものを無効にするという選択肢は取りたくない……。
そこで、一部のキーだけ暗号化させない方法を調べました。
EncryptCookiesクラスのコードを読んでみると、
protectedなプロパティである$exceptに登録されているキーは暗号化しないという処理になっています。
方法1 EncryptCookiesクラスを継承して暗号化対象外のキーを設定する
元のクラスを継承したクラスを用意し、
●app/Http/Middleware/EncryptCookies
<?php namespace App\Http\Middleware;
use \Illuminate\Cookie\Middleware\EncryptCookies as DefaultEncryptCookies
class EncryptCookies extends DefaultEncryptCookies {
protected $except = ['plain_cookie_key'];
}
利用するミドルウェアも差し替えます
●app/Http/Kernel.php
(略)
class Kernel extends HttpKernel {
/**
* The application's global HTTP middleware stack.
*
* @var array
*/
protected $middleware = [
(略)
\App\Http\Middleware\EncryptCookies::class,
(略)
];
(略)
これだけのためにクラス継承するのもどうかなと思いますよね。もうすこし詳しく見てみると
暗号化対象外のキーを外部から追加するためにEncryptCookies::disableFor()というpublicなメソッドが用意されていることがわかります。
方法2 publicメソッドで暗号化対象外のキーを設定し、 サービスプロバイダでシングルトン登録しておく
●app/Providers/AppServiceProvider
<?php namespace App\Providers;
use Illuminate\Foundation\Application;
use Illuminate\Cookie\Middleware\EncryptCookies;
use Illuminate\Contracts\Encryption\Encrypter;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider {
public function register()
{
$this->app->singleton(EncryptCookies::class, function(Application $app) {
$middleware = new EncryptCookies($app->make(Encrypter::class));
$middleware->disableFor('plain_cookie_key');
return $middleware;
});
}
}
これでEncryptCookiesがミドルウェアとして利用される際には事前設定済みのオブジェクトが利用されるようになります。