Slide 1

Slide 1 text

の高速開発を支える Laravel 株式会社ラクス 坂田晃平 PHP カンファレンス関西 2018

Slide 2

Slide 2 text

自己紹介 • 名前:坂田 晃平 • 所属:株式会社ラクス – メールディーラーと チャットディーラーの開発を担当 • 経歴: – 2016 年 新卒入社(3 年目) – PHP の使用歴も 3 年目 • メールディーラー :ノンフレームワーク • チャットディーラー:Laravel 1

Slide 3

Slide 3 text

• はじめに • チャットディーラー(ChatDealer)とは • なぜ Laravel を選択したか? • Laravel で良かったこと • Laravel で困ったこと • まとめ 今日話すこと 2

Slide 4

Slide 4 text

はじめに 3

Slide 5

Slide 5 text

10 年以上 PHP でノンフレームワークで開発・運用されてきた主力サービ ス(メールディーラー)の開発チームが、新規に姉妹サービス(チャット ディーラー)を立ち上げる際に Laravel を選択をしました。 開発期間半年というスピードが求められる中で、チームが Laravel に抱い た理想と現実、また、Laravel (Blade) と Vue.js の組み合わせにより発生 した脆弱性への対応など、Laravel での新規サービス立ち上げの経験を具 体的にお伝えします。 <セッション概要>より 4

Slide 6

Slide 6 text

5 https://www.maildealer.jp/products/ メールディーラー(MailDealer)とは • 問合せメールを一元的に管理・共有する メール対応サポートツール(SaaS)

Slide 7

Slide 7 text

• 2001 年にサービス提供開始 • 4,000 社以上の導入実績 • メール共有・管理システム市場で 9 年連続 シェア No.1 6 メールディーラー(MailDealer)とは

Slide 8

Slide 8 text

• 2001 年にサービス提供開始 • 4,000 社以上の導入実績 • メール共有・管理システム市場で 9 年連続 シェア No.1 • PHP でノンフレームワークで開発 7 メールディーラー(MailDealer)とは

Slide 9

Slide 9 text

• PHP 4 時代にサービスの土台を開発 (参考) PHP 4.0 リリースが 2000/05/22 • 長期間改修されてきたソースコード – ソースコードの構成が機能ごとにちぐはぐ – ビューとロジックが分離されていない – リクエストパラメータの受け渡しが煩雑 – バリデーションが煩雑 – etc… • メンテナンス性の低下 8 課題

Slide 10

Slide 10 text

• PHP 4 時代にサービスの土台を開発 (参考) PHP 4.0 リリースが 2000/05/22 • 長期間改修されてきたソースコード – ソースコードの構成が機能ごとにちぐはぐ – ビューとロジックが分離されていない – リクエストパラメータの受け渡しが煩雑 – バリデーションが煩雑 – etc… • メンテナンス性の低下 9 課題 課題感をもつ開発チームが新サービスを立ち上げ!

Slide 11

Slide 11 text

チャットディーラー(ChatDealer)とは 10

Slide 12

Slide 12 text

サービス概要 • Web ページに専用スクリプトを埋め込んで 利用する Web チャットシステム(SaaS) • 本文 11 https://www.chatdealer.jp/products/

Slide 13

Slide 13 text

サービス概要 • Web ページに専用スクリプトを埋め込んで 利用する Web チャットシステム(SaaS) • 本文 12 https://www.chatdealer.jp/products/

Slide 14

Slide 14 text

技術スタック • 言語、フレームワーク – PHP 7.1、Laravel 5.5 – Node.js、Express、Socket.IO • 開発環境 – PhpStorm、Jenkins、Redmine、GitLab、 Mattermost • インフラ – 仮想基盤(オンプレ)、nginx、Apache、 PostgreSQL 9.6、Redis 13

Slide 15

Slide 15 text

開発チーム構成 • プロジェクトマネージャー • エンジニア – toB 向けバックエンド (PHP):3名 – toC 向けフロントエンド (Node.js):3名 14

Slide 16

Slide 16 text

開発スケジュール 15 2月 3月 4月 5月 6月 7月 要件定義 2017年 開発基盤整備 設計 実装・単体テスト システム テスト β版フィード バック改修 β版リリース 本番リリース

Slide 17

Slide 17 text

なぜ Laravel を選択したか? 16

Slide 18

Slide 18 text

はじめに • 新サービスの立ち上げに際しての課題 – 短納期(6 ヶ月) • 実装の期間は実質 2 ヶ月 • 開発効率の向上必須 – レガシーからの脱却 • レガシーシステムの課題を解決 • 開発チームはフレームワークを使っていない 17

Slide 19

Slide 19 text

18 レガシーシステムでの課題(再掲) • PHP 4 時代にサービスの土台を開発 • 長期間改修されてきたソースコード – ソースコードの構成が機能ごとにちぐはぐ – ビューとロジックが分離されていない – リクエストパラメータの受け渡しが煩雑 – バリデーションが煩雑 – etc… • メンテナンス性の低下

Slide 20

Slide 20 text

• 実装工数の短縮 • メンテナンス性の向上 – MVC モデルによるコードの分離 – コーディングルールやファイル構成の標準化 – リクエスト情報の管理方法の標準化 – 一般的な脆弱性への対策 19 フレームワークに期待すること

Slide 21

Slide 21 text

フレームワーク選定 • フレームワークに期待する要件は次の2点 – 長期サポート – 機能性 20

Slide 22

Slide 22 text

選定条件:長期サポート • すぐにサポート切れしてはメンテナンス性が 悪くなる • 長期サポートされる条件を検討 – 使用者数が多く、人気がある – 活発なコミュニティ – LTS (Long-Term Support) を宣言している 21

Slide 23

Slide 23 text

選定条件:長期サポート • シェア率が高い人気のフレームワークを調査 – 調査段階では、日本では CakePHP に続き Laravel がシェア 2 位だった – 世界では Laravel が圧倒的に使用されている – Laravel のシェア率の伸びが一番大きい – コミュニティが活発 22

Slide 24

Slide 24 text

選定条件:長期サポート https://trends.google.co.jp/trends/explore?date=today%205- y&q=Laravel,CakePHP,Symfony,CodeIgniter,FuelPHP 23 • Google トレンドでの比較 Laravel は一番人気 があり、上昇し続け ている

Slide 25

Slide 25 text

選定条件:長期サポート • Laravel は LTS に対応 – Laravel 5.1 より LTS に対応した – バグフィックスは 2 年間、セキュリティーパッ チの提供は 3 年間 – 新サービス開発開始の半年後に新たな LTS バー ジョン (5.5) がリリース予定 24

Slide 26

Slide 26 text

選定条件:機能性 • 基本機能 – ルーティング – テンプレートエンジン (Blade) – 扱いやすいバリデーター – 認証、セッション管理、エラーハンドリング等 の基本機能 – 一般的な脆弱性への対策 25

Slide 27

Slide 27 text

選定条件:機能性 • 便利機能やライブラリを調査 – マイグレーション – ページネーション – 様々なミドルウェアやサービスと連携できる • Redis でのキャッシュ管理など – 主要なライブラリが含まれる • Bootstrap, jQuery, Vue.js など – ユニットテストの作成が容易 • PHPUnit をサポート 26

Slide 28

Slide 28 text

フレームワーク選定のまとめ 下記の点から、 新サービスのフレームワークに Laravel を採用する事となった • 長期サポート – LTS バージョンがある – 一番人気で、今なお人気上昇中 – コミュニティも活発 • 機能性 – フルスタックフレームワークであること 27

Slide 29

Slide 29 text

Laravel で良かったこと 28

Slide 30

Slide 30 text

Laravel で良かったこと • オールインワンでスピード開発に向いていた • 簡単設定でどんなものにも繋がる • 標準ライブラリが使いやすい • ドキュメントが充実していた 29

Slide 31

Slide 31 text

Laravel で良かったこと • オールインワンでスピード開発に向いていた • 簡単設定でどんなものにも繋がる • 標準ライブラリが使いやすい • ドキュメントが充実していた 30

Slide 32

Slide 32 text

オールインワンでスピード開発に向いていた • 準備コストが削減できたので、ロケットス タートを決めることができた – フレームワークの標準機能 ルーティング、Middleware、DI、バリデーション、 テンプレートエンジン (Blade)、バッチ処理 (Command)、 マイグレーション、デバッグ、クエリビルダ、ページネーション、 セッション – ライブラリ、ミドルウェア・サービスとの統合 Composer、Bootstrap、jQuery、Vue.js、PostgreSQL、 Redis、PHPUnit 31

Slide 33

Slide 33 text

Laravel で良かったこと • オールインワンでスピード開発に向いていた • 簡単設定でどんなものにも繋がる • 標準ライブラリが使いやすい • ドキュメントが充実していた 32

Slide 34

Slide 34 text

簡単設定でどんなものにも繋がる • チャットディーラーで利用しているミドル ウェアの一例 – PostgreSQL – Redis – Postfix いずれも、接続のための仕組みは準備されており、 簡単設定で繋がった 33

Slide 35

Slide 35 text

Laravel で良かったこと • オールインワンでスピード開発に向いていた • 簡単設定でどんなものにも繋がる • 標準ライブラリが使いやすい • ドキュメントが充実していた 34

Slide 36

Slide 36 text

標準ライブラリが使いやすい • ルーティング – URL とコントローラの紐づけが直観的に書けて わかりやすかった 35

Slide 37

Slide 37 text

標準ライブラリが使いやすい • Middleware – HTTP リクエストをフィルタリングする機能 – リクエスト処理の事前チェックや事後処理を Middleware に実装、適用したいルーティング設 定を group メソッドで囲うだけ – 認証処理などを Middleware に実装にしたこと で、ビジネスロジックに専念できた 36

Slide 38

Slide 38 text

標準ライブラリが使いやすい • DI – メソッドインジェクション機能が便利 – タイプヒントするだけで、メソッドの引数にオ ブジェクト注入される 37

Slide 39

Slide 39 text

標準ライブラリが使いやすい • バリデーション – Request クラスにバリデーションルールを追加 し、コントローラーメソッドでタイプヒントす るだけ – コントローラーメソッドに、バリデーション処 理を実装をする必要がなくなった 38

Slide 40

Slide 40 text

• バリデーション – バラエティ豊富なバリデーションルール 標準ライブラリが使いやすい 39 https://readouble.com/laravel/5.5/ja/validation.html

Slide 41

Slide 41 text

標準ライブラリが使いやすい • テンプレートエンジン(Blade) – 覚えることが少なく、なじみやすいシンタック ス – Blade ファイルは PHP ファイルにコンパイルさ れ、変更が無い限りはコンパイルした PHP ファ イルを呼び出すので軽量(らしい) – 他のテンプレートエンジンとくらべ制約が緩く、 @php ディレクティブで PHP コードの記述もで きる 40

Slide 42

Slide 42 text

標準ライブラリが使いやすい 41 • テンプレートエンジン(Blade) – ノンフレームワークサービスの場合

Slide 43

Slide 43 text

• テンプレートエンジン(Blade) – Laravel の場合 標準ライブラリが使いやすい 画面ごとに切替えたいコンテンツを @yield ディレクティブで指定する 42 @section ディレクティブ内に 挿入するコンテンツを記述する

Slide 44

Slide 44 text

標準ライブラリが使いやすい • バッチ処理(Command) – cron レコードは 1 件、実行スケジュールを PHP 内に記述できるようになり管理が楽になっ た 43

Slide 45

Slide 45 text

• バッチ処理(Command) – ノンフレームワークサービスの場合 標準ライブラリが使いやすい バージョンアップを重ねていく内に cron レコードが増えていく 44

Slide 46

Slide 46 text

• バッチ処理(Command) – Laravel の場合 • cron は 1 レコードのみ • 実行スケジュールを PHP で記述できる 標準ライブラリが使いやすい 45

Slide 47

Slide 47 text

標準ライブラリが使いやすい • マイグレーション – DB の移行パッチの適用管理が楽になった 46

Slide 48

Slide 48 text

• マイグレーション – ノンフレームワークサービスの場合 – Laravel の場合 アプリケーションのバージョンより、 新しいバージョンをファイル名に含 むパッチファイルを実行 コマンドを実行するだけで、マイグ レーションファイルの中から未実行 のファイルのみを自動実行 ロールバックも可能 47 標準ライブラリが使いやすい

Slide 49

Slide 49 text

標準ライブラリが使いやすい • デバッグ – Laravel をバージョンアップ (5.4→5.5) 後、デ バッグモード時のエラーページの情報量がすご かった – デバッグ時間の大幅短縮することができた 48

Slide 50

Slide 50 text

標準ライブラリが使いやすい エラーメッセージ スーパーグローバル、 環境情報など スタックトレース エラー発生箇所 49 • デバッグ

Slide 51

Slide 51 text

Laravel で良かったこと • オールインワンでスピード開発に向いていた • 簡単設定でどんなものにも繋がる • 標準ライブラリが使いやすい • ドキュメントが充実していた 50

Slide 52

Slide 52 text

ドキュメントが充実していた • 必要な情報が公式ドキュメントとして準備さ れていた 51 http://laravel.jp/

Slide 53

Slide 53 text

ドキュメントが充実していた • 公式ドキュメントが日本語化されていた 52 https://readouble.com/laravel/5.5/ja/

Slide 54

Slide 54 text

Laravel で困ったこと 53

Slide 55

Slide 55 text

Laravel で困ったこと • Blade (SSR) + Vue.js での脆弱性 • Vue.js は思ったより難しかった 54

Slide 56

Slide 56 text

Laravel で困ったこと • Blade (SSR) + Vue.js での脆弱性 • Vue.js は思ったより難しかった 55

Slide 57

Slide 57 text

Blade (SSR) + Vue.js での脆弱性 • Laravel 標準の認証画面に XSS の問題 – ある時のリリースノート > In Laravel 5.6.9 and Laravel 5.5.37, a potential XSS > vector was patched in the default Bootstrap > scaffolding that ships with laravel. > Laravel 5.6.9 と 5.5.37 では、標準のスキャフォール > ディングで、潜在的な XSS の可能性が修正されました。 https://laravel-news.com/laravel-5-6-9 56

Slide 58

Slide 58 text

• Laravel 標準の認証画面に XSS の問題 – ある時のリリースノート > In Laravel 5.6.9 and Laravel 5.5.37, a potential XSS > vector was patched in the default Bootstrap > scaffolding that ships with laravel. Laravel 5.6.9 と 5.5.37 では、標準のスキャフォールディ ングで、潜在的な XSS の可能性が修正されました Blade (SSR) + Vue.js での脆弱性 https://laravel-news.com/laravel-5-6-9 57 XSS なんて怖いわぁ…。 標準のスキャフォールディングは使っ てないし関係ないっぽいけど。 でも、どこで XSS になってるんやろ?

Slide 59

Slide 59 text

• Laravel 標準の認証画面に XSS の問題 – ある時のリリースノート > In Laravel 5.6.9 and Laravel 5.5.37, a potential XSS > vector was patched in the default Bootstrap > scaffolding that ships with laravel. Laravel 5.6.9 と 5.5.37 では、標準のスキャフォールディ ングで、潜在的な XSS の可能性が修正されました Blade (SSR) + Vue.js での脆弱性 https://laravel-news.com/laravel-5-6-9 58 XSS なんて怖いわぁ…。 標準のスキャフォールディングは使っ てないし関係ないっぽいけど。 でも、どこで XSS になってるんやろ? 実は、、、関係あった! (調べてよかった…)

Slide 60

Slide 60 text

Blade (SSR) + Vue.js での脆弱性 • サーバーサイドレンダリング (SSR) と Vue.js との組み合わせで起こりうる XSS – Blade との組み合わせに限らない – 実は Vue.js 特有というわけでもない • AngulerJS ではもっと前(2014 年くらい)から話題 になっていたらしい https://havelog.ayumusato.com/develop/security/e593- mixins_server_template_and_angular.html 59

Slide 61

Slide 61 text

• SSR と Vue.js の組み合わせで起こる XSS サーバーでの処理 ブラウザでの処理 Blade (SSR) + Vue.js での脆弱性
{{ $name }}
sample.blade.php Blade で処理 $name = “{{ alert(‘XSS') }}”
{{ alert('XSS') }}
{{ alert(‘XSS’) }}
Vue.js が処理
60 {{ … }} の中の スクリプトが実行 される! 処理済みのHTMLデータ レスポンス送信 ブラウザが読込

Slide 62

Slide 62 text

• SSR と Vue.js の組み合わせで起こる XSS サーバーでの処理 ブラウザでの処理 Blade (SSR) + Vue.js での脆弱性
{{ $name }}
sample.blade.php Blade で処理 $name = “{{ alert(‘XSS') }}”
{{ alert('XSS') }}
{{ alert(‘XSS’) }}
Vue.js が処理
61 {{ … }} の中の スクリプトが実行 される! 処理済みのHTMLデータ レスポンス送信 ブラウザが読込

Slide 63

Slide 63 text

• SSR と Vue.js の組み合わせで起こる XSS – Vue.js で処理される領域にユーザー入力の文字 列を SSR で埋め込むと危険 – “mustache injection” と(個人的に)呼んで る {{…}} ← これを Mustache 構文と呼ぶことから – 知らなかったら普通に作ってしまいそう Blade (SSR) + Vue.js での脆弱性 62

Slide 64

Slide 64 text

• SSR と Vue.js の組み合わせで起こる XSS – Vue.js で処理される領域にユーザー入力の文字 列を SSR で埋め込むと危険 – “mustache injection” と(個人的に)呼んで る {{…}} ← これを Mustache 構文と呼ぶことから – 知らなかったら普通に作ってしまいそう • 知らなかったし、実際作ってしまっていた Blade (SSR) + Vue.js での脆弱性 63

Slide 65

Slide 65 text

Blade (SSR) + Vue.js での脆弱性 • mustache injection 対策案1 (不採用) – “{” や “}” を HTML エスケープ • 効果なし サーバー側でエスケープしても、Vue.js が処理する 時にはブラウザによってもとに戻されてしまっている 64 サーバーでの処理
{{ alert('XSS') }}
{{ escapeMustache($name) }}
sample2.blade.php ブラウザでの処理
{{ alert(‘XSS’) }}
$name = “{{ alert(‘XSS') }}”

Slide 66

Slide 66 text

Blade (SSR) + Vue.js での脆弱性 • mustache injection 対策案2 (不採用) – “v-pre” ディレクティブの利用 • Laravel のスキャフォールディングでの対策 • 効果は実証されている • 結果:対象箇所が多すぎる・新しく書く時も必ずつけ る必要・忘れそう 65 ブラウザでの処理
{{ alert(‘XSS’) }}
v-pre の要素内は Vue.js で処理されない

Slide 67

Slide 67 text

Blade (SSR) + Vue.js での脆弱性 • mustache injection 対策案3 (不採用) – “{{” や “}}” の文字間に半角空白を挿入する • “{” や “}” のHTMLエンティティ表現に対しても同様 に処理が必要 ↓ • “{”、“{”、“{” のうち 2 つの組み合わせ • “}”、“}”、“}” のうち 2 つの組み合わせ • さらにそれらが連続している場合でも漏れなく空白を 入れる必要がある 66 サーバーでの処理 {{{{{ … }}}}} 危険な文字列: { { { { { … } } } } } 無害な文字列:

Slide 68

Slide 68 text

Blade (SSR) + Vue.js での脆弱性 • mustache injection 対策案 (3) – “{{” や “}}” の文字間に半角空白を挿入する • “{” や “}” のエンティティ表現に対しても同様に処理 が必要 ↓ • “{”、“{”、“{” のうち 2 つの組み合わせ • “}”、“}”、“}” のうち 2 つの組み合わせ • さらにそれらが連続している場合でも漏れなく空白を 入れる必要がある 67 サーバーでの処理 {{{{{ … }}}}} 危険な文字列: { { { { { … } } } } } 無害な文字列: $replacementMap = [ "{{" => "{ {" , "{{" => "{ {" , "{{" => "{ {" , "{{" => "{ {" , "{{" => "{ {" , "{{" => "{ {" , "{{" => "{ {" , "{{" => "{ {" , "{{" => "{ {" , "}}" => "} }" , "}}" => "} }" , "}}" => "} }" , "}}" => "} }" , "}}" => "} }" , "}}" => "} }" , "}}" => "} }" , "}}" => "} }" , "}}" => "} }" ];

Slide 69

Slide 69 text

Blade (SSR) + Vue.js での脆弱性 • mustache injection 対策案4 (採用) – “{{” や “}}” の文字間に半角空白を挿入する – いつやるか? • 出力時 ⇒ “v-pre” 使用と同様の問題。対象箇所が多い・忘れ そう • 入力時 ⇒ Middleware ですべてのリクエストパラメータを処 理すれば確実 – 根本的な解決は…(^ω^; • SPA 化しかない? 68

Slide 70

Slide 70 text

Laravel で困ったこと • Blade (SSR) + Vue.js での脆弱性 • Vue.js は思ったより難しかった 69

Slide 71

Slide 71 text

Vue.js は思ったより難しかった 70 • 開発を始める前は… – チームメンバーはみな jQuery に慣れ親しんで いる(特にベテラン) – Vue.js は「学習コストが低い」という前評判 – 軽く公式のガイドを見てもそんな印象 • 内容を表示させたい場所に `v-bind:` ってつければ 表示される! • しかもモデルの値を変えたら自動で反映される! – 確かに簡単そうだ(と思ってしまった) • そのまま開発に突入

Slide 72

Slide 72 text

Vue.js は思ったより難しかった 71 • 開発を始めてみると… – Vue インスタンスが紐づいた要素内の子要素を 別の Vue インスタンスで制御したい – 離れた場所にある別々の要素を同じ Vue インス タンスで制御したい – jQuery や Bootstrap のライブラリと一緒に使 いたい – モデルの値を変えてるはずなのに反映されない

Slide 73

Slide 73 text

Vue.js は思ったより難しかった 72 • 開発を始めてみると… – Vue インスタンスが紐づいた要素内の子要素を 別の Vue インスタンスで制御したい – 離れた場所にある別々の要素を同じVueインスタ ンスで制御したい – jQuery や Bootstrap のライブラリと一緒に使 いたい – モデルの値を変えてるはずなのに反映されない いったいどうすればいいの…?

Slide 74

Slide 74 text

Vue.js は思ったより難しかった 73 • 開発を始めてみると… – Vue インスタンスが紐づいた要素内の子要素を 別の Vue インスタンスで制御したい ⇒ 内部の要素はコンポーネントを作ってそれで置き換 えましょう – 内部の要素に `v-pre` を付けてもできるけど… – 離れた場所にある別々の要素を同じ Vue インス タンスで制御したい ⇒ コンポーネントにすれば再利用できます

Slide 75

Slide 75 text

Vue.js は思ったより難しかった 74 • 開発を始めてみると… – jQuery や Bootstrap のライブラリと一緒に使 いたい ⇒ ラッパーコンポーネントを作れば比較的楽に統合で きます – モデルの値を変えてるはずなのに反映されない ⇒ 配列やオブジェクトの要素を変更する場合は特別な やり方があるので注意!

Slide 76

Slide 76 text

Vue.js は思ったより難しかった 75 • jQuery 脳からのパラダイムシフトが必要? – 「jQuery でなら作り方わかってるのに」 – 利き手でない方の手で字を書くかのよう… – 結局慣れるしかない • jQuery 系ライブラリとの相性 – 仮想 DOM から DOM への変更が実際に反映さ れるのを待つ必要あり – ノウハウの蓄積

Slide 77

Slide 77 text

Vue.js は思ったより難しかった 76 • 「学習コストが低い」とは言え、やっぱり ちゃんと勉強しないとだめだった – 最近は日本語で読める入門記事もどんどん増え ていて学習しやすくなっている印象 • 少し複雑なことをしたいときはコンポーネン ト化が必須 – コンポーネントの考え方が分かりにくいとの声 もあるが – そこは勉強してもらうしかない

Slide 78

Slide 78 text

まとめ 77

Slide 79

Slide 79 text

まとめ • フレームワークがスピード開発に役立った – ミドルウェアとの連携設定 – MVC の考えに沿ったソース配置 – ビジネスロジックへの集中ができた! • とくに Laravel で良かったこと – 豊富な機能 – 日本語公式ドキュメント – 活発なコミュニティ • 脆弱性への対応も早かった 78

Slide 80

Slide 80 text

まとめ • Vue.js との組み合わせには注意 – 脆弱性への対応を後からするのは大変 • Vue.js もちゃんと勉強しよう • Laravel の豊富な機能を使いこなせない – アイデアをぜひ教えてほしいです! 79

Slide 81

Slide 81 text

PHP エンジニア 募集中 www.facebook.com/rakus.career 80