Slide 1

Slide 1 text

の高速開発を支える Laravel 株式会社ラクス 坂田晃平 Laravel JP Conference 2019

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

宣伝 Meetup / もくもく会 やってます! 2 ぜひイベント フォローしてね! Twitter:@DevRakus Tech Blog:http://tech-blog.rakus.co.jp/ rakus.connpass.com

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

はじめに 4

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

なぜ Laravel を選択したか? 16

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

フレームワーク選定 フレームワークに期待する要件は次の2点 • 長期サポート – サポート切れしてはメンテナンス性が悪い • 機能性 – いろんな便利機能がある方がいい 22

Slide 23

Slide 23 text

選定条件:長期サポート • 長期サポートされる条件 – 使用者数が多い(人気がある) – コミュニティが活発 – LTS (Long-Term Support) を宣言 23

Slide 24

Slide 24 text

選定条件:長期サポート • フレームワーク人気調査 – 日本でのシェア(調査時点) • 1位 CakePHP • 2位 Laravel – 世界でのシェア(調査時点) • 圧倒的1位 Laravel 24

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

選定条件:機能性 • 便利機能やライブラリ – マイグレーション – ページネーション – ミドルウェアやサービスとの連携 – JSライブラリ – Bootstrap, jQuery, Vue.js など – ユニットテスト 28

Slide 29

Slide 29 text

フレームワーク選定のまとめ Laravel に決めた! • 長期サポート – LTS バージョンがある – 一番人気で、今なお人気上昇中 – コミュニティも活発 • 機能性 – フルスタックフレームワーク 29

Slide 30

Slide 30 text

Laravel で良かったこと 30

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

Laravel で良かったこと • ノンフレームワークだと… – ルーティングどうしよう? – リクエストごとの共通処理はどこに書けば? – バリデーション漏れないようにしたいけど… – ビューとロジックの境界が曖昧になってしまう – DB との接続はどうすれば?共通化したいよね – etc 33

Slide 34

Slide 34 text

Laravel で良かったこと • Laravelを使えば… – ルーティングはデフォルトの仕組みを使おう – Middleware で共通処理をやろう – Request クラスにルールを書こう – ロジックは Service クラス、ビューは Blade で – Config で設定して後はクエリビルダで DB 使おう – etc 34

Slide 35

Slide 35 text

Laravel で良かったこと • Laravelを使えば… – ルーティングはデフォルトの仕組みを使おう – Middleware で共通処理をやろう – Request クラスにルールを書こう – ロジックは Service クラス、ビューは Blade で – Config で設定して後はクエリビルダで DB 使おう – etc 35 フレームワークってこんなに便利なんだ

Slide 36

Slide 36 text

Laravel で困ったこと 36

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

Blade + 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 39

Slide 40

Slide 40 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 + Vue.js での脆弱性 https://laravel-news.com/laravel-5-6-9 40 XSS なんて怖いわぁ…。 標準のスキャフォールディングは使っ てないし関係ないっぽいけど。 でも、どこで XSS になってるんやろ?

Slide 41

Slide 41 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 + Vue.js での脆弱性 https://laravel-news.com/laravel-5-6-9 41 XSS なんて怖いわぁ…。 標準のスキャフォールディングは使っ てないし関係ないっぽいけど。 でも、どこで XSS になってるんやろ? 実は、、、関係あった! (調べてよかった…)

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

Vue.js は思ったより難しかった 53 • 開発を始める前は… – チームメンバーはみな jQuery に慣れ親しんで いる(特にベテラン) – Vue.js は「学習コストが低い」という前評判 – 軽く公式のガイドを見てもそんな印象

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

Vue.js は思ったより難しかった 56 • 開発を始めてみると… Vue インスタンス入れ子 にしたいんだけど… Vueインスタンスって 飛び地にできないの? モデルの値を変えてるは ずなのに反映されない… Bootstrap一緒に使いた いけどうまくいかない…

Slide 57

Slide 57 text

Vue.js は思ったより難しかった 57 • 開発を始めてみると… いったいどうすればいいの…? Vue インスタンス入れ子 にしたいんだけど… Vueインスタンスって 飛び地にできないの? モデルの値を変えてるは ずなのに反映されない… Bootstrap一緒に使いた いけどうまくいかない…

Slide 58

Slide 58 text

Vue.js は思ったより難しかった 58 • 調べながら実装を進める… 内部の要素はコンポーネントを 作ってそれで置き換えましょう Vue インスタンス入れ子 にしたいんだけど…

Slide 59

Slide 59 text

Vue.js は思ったより難しかった 59 • 調べながら実装を進める… インスタンスのマウント範囲は 広めにとって、実際の制御はコ ンポーネントにしましょう。 コンポーネントにすれば再利用 できます。 Vueインスタンスって 飛び地にできないの?

Slide 60

Slide 60 text

Vue.js は思ったより難しかった 60 • なんとか解決することはできるが ラッパーコンポーネントを作れ ば比較的楽に統合できます Bootstrap一緒に使いた いけどうまくいかない…

Slide 61

Slide 61 text

Vue.js は思ったより難しかった 61 • そこに行きつくまでに時間がかかった… 配列の要素を変更する場合や、 オブジェクトに要素を追加す る場合は特別なやり方がある ので注意! モデルの値を変えてるは ずなのに反映されない…

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

Vue.js は思ったより難しかった 63 • やっぱりちゃんと勉強しないとだめだった – 学習資料も限られていた – 最近は充実してきている • コンポーネントの理解は必須 – 分かりにくいとの声もあるが – そこは勉強してもらうしかない

Slide 64

Slide 64 text

まとめ 64

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

まとめ • Vue.js との組み合わせには注意 – 脆弱性への対応を後からするのは大変 • Vue.js もちゃんと勉強しよう – Vue.jsチュートリアル作成中… 66