チャットディーラーの高速開発を支えるLaravel / laraveljpcon ChatDealer Rapid Development with Laravel

97a42cc1630ebdfdaaa8d50078a9fd3d?s=47 坂田晃平
February 16, 2019

チャットディーラーの高速開発を支えるLaravel / laraveljpcon ChatDealer Rapid Development with Laravel

97a42cc1630ebdfdaaa8d50078a9fd3d?s=128

坂田晃平

February 16, 2019
Tweet

Transcript

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

  2. 自己紹介 • 名前:坂田 晃平 • 所属:株式会社ラクス – メールディーラーと チャットディーラーの開発を担当 •

    経歴: – 2016 年 新卒入社(3 年目) – PHP の使用歴も 3 年目 • メールディーラー :ノンフレームワーク • チャットディーラー:Laravel 1
  3. 宣伝 Meetup / もくもく会 やってます! 2 ぜひイベント フォローしてね! Twitter:@DevRakus Tech

    Blog:http://tech-blog.rakus.co.jp/ rakus.connpass.com
  4. • はじめに • チャットディーラー(ChatDealer)とは • なぜ Laravel を選択したか? • Laravel

    で良かったこと • Laravel で困ったこと • まとめ 今日話すこと 3
  5. はじめに 4

  6. 10 年以上 PHP でノンフレームワークで開発・運用されてきた主力サービ ス(メールディーラー)の開発チームが、新規に姉妹サービス(チャット ディーラー)を立ち上げる際に Laravel を選択をしました。 開発期間半年というスピードが求められる中で、チームが Laravel

    に抱い た理想と現実、また、Laravel (Blade) と Vue.js の組み合わせにより発生 した脆弱性への対応など、Laravel での新規サービス立ち上げの経験を具 体的にお伝えします。 <セッション概要>より 5
  7. 6 https://www.maildealer.jp/products/ メールディーラー(MailDealer)とは • 問合せメールを一元的に管理・共有する メール対応サポートツール(SaaS)

  8. • 2001 年にサービス提供開始 • 4,000 社以上の導入実績 • メール共有・管理システム市場で 9 年連続

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

    シェア No.1 • PHP でノンフレームワークで開発 8 メールディーラー(MailDealer)とは
  10. • PHP 4 時代にサービスの土台を開発 (参考) PHP 4.0 リリースが 2000/05/22 •

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

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

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

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

    https://www.chatdealer.jp/products/
  15. 技術スタック • 言語、フレームワーク – PHP 7.1、Laravel 5.5 – Node.js、Express、Socket.IO •

    開発環境 – PhpStorm、Jenkins、Redmine、GitLab、 Mattermost • インフラ – 仮想基盤(オンプレ)、nginx、Apache、 PostgreSQL 9.6、Redis 14
  16. なぜ Laravel を選択したか? 16

  17. はじめに • 新サービスの立ち上げに際しての課題 – 短納期(6 ヶ月) • 実装の期間は実質 2 ヶ月

    • 開発効率の向上必須 – レガシーからの脱却 • レガシーシステムの課題を解決 • 開発チームはフレームワークを使っていない 17
  18. 開発スケジュール 18 2月 3月 4月 5月 6月 7月 要件定義 2017年

    開発基盤整備 設計 実装・単体テスト システム テスト β版フィード バック改修 β版リリース 本番リリース
  19. はじめに • 新サービスの立ち上げに際しての課題 – 短納期(6 ヶ月) • 実装の期間は実質 2 ヶ月

    • 開発効率の向上必須 – レガシーからの脱却 • レガシーシステムの課題を解決 • 開発チームはフレームワークを使っていない 19
  20. 20 レガシーシステムでの課題(再掲) • ノンフレームワーク &長期間改修されてきたソースコード – ソースコードの構成が機能ごとにちぐはぐ – ビューとロジックが分離されていない –

    リクエストパラメータの受け渡しが煩雑 – バリデーションが煩雑 – etc… • メンテナンス性の低下
  21. • 実装工数の短縮 • メンテナンス性の向上 – MVC モデルによるコードの分離 – コーディングルールやファイル構成の標準化 –

    リクエスト情報の管理方法の標準化 – 一般的な脆弱性への対策 21 フレームワークに期待すること
  22. フレームワーク選定 フレームワークに期待する要件は次の2点 • 長期サポート – サポート切れしてはメンテナンス性が悪い • 機能性 – いろんな便利機能がある方がいい

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

    Support) を宣言 23
  24. 選定条件:長期サポート • フレームワーク人気調査 – 日本でのシェア(調査時点) • 1位 CakePHP • 2位

    Laravel – 世界でのシェア(調査時点) • 圧倒的1位 Laravel 24
  25. 選定条件:長期サポート https://trends.google.co.jp/trends/explore?date=today%205- y&q=Laravel,CakePHP,Symfony,CodeIgniter,FuelPHP 25 • Google トレンドでの比較 Laravel は一番人気 があり、上昇し続け

    ている
  26. 選定条件:長期サポート • Laravel は LTS に対応 – Laravel 5.1 より

    LTS に対応 – バグフィックスは 2 年間 – セキュリティーパッチ提供は 3 年間 – 新サービス開発開始の半年後に新たな LTS バー ジョン (5.5) がリリース予定 26
  27. 選定条件:機能性 • 基本機能 – ルーティング – テンプレートエンジン (Blade) – 扱いやすいバリデーター

    – 認証、セッション管理、エラーハンドリング等 – 脆弱性対策 27
  28. 選定条件:機能性 • 便利機能やライブラリ – マイグレーション – ページネーション – ミドルウェアやサービスとの連携 –

    JSライブラリ – Bootstrap, jQuery, Vue.js など – ユニットテスト 28
  29. フレームワーク選定のまとめ Laravel に決めた! • 長期サポート – LTS バージョンがある – 一番人気で、今なお人気上昇中

    – コミュニティも活発 • 機能性 – フルスタックフレームワーク 29
  30. Laravel で良かったこと 30

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

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

    • etc 32 面倒なことは大抵 Laravel さんが うまいことやってくれた
  33. Laravel で良かったこと • ノンフレームワークだと… – ルーティングどうしよう? – リクエストごとの共通処理はどこに書けば? – バリデーション漏れないようにしたいけど…

    – ビューとロジックの境界が曖昧になってしまう – DB との接続はどうすれば?共通化したいよね – etc 33
  34. Laravel で良かったこと • Laravelを使えば… – ルーティングはデフォルトの仕組みを使おう – Middleware で共通処理をやろう –

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

    Request クラスにルールを書こう – ロジックは Service クラス、ビューは Blade で – Config で設定して後はクエリビルダで DB 使おう – etc 35 フレームワークってこんなに便利なんだ
  36. Laravel で困ったこと 36

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

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

    38
  39. 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
  40. • 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 になってるんやろ?
  41. • 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 になってるんやろ? 実は、、、関係あった! (調べてよかった…)
  42. 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
  43. • Bladeと Vue.js の組み合わせで起こる XSS サーバーでの処理 ブラウザでの処理 Blade + Vue.js

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

    での脆弱性 <div id="app"> {{ $name }} </div> sample.blade.php Blade で処理 $name = “{{ alert(‘XSS') }}” <div id="app"> {{ alert(&apos;XSS&apos;) }} </div> <div id="app"> {{ alert(‘XSS’) }} </div> Vue.js が処理 <div id="app"> </div> 44 {{ … }} の中の スクリプトが実行 される! 処理済みのHTMLデータ レスポンス送信 ブラウザが読込
  45. • Blade と Vue.js の組み合わせで起こる XSS – Vue.js で処理される領域にユーザー入力の文字 列をサーバー処理で埋め込むと危険

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

    – “mustache injection” と(個人的に)呼んで る {{…}} ← これを Mustache 構文と呼ぶことから – 知らなかったら普通に作ってしまいそう Blade + Vue.js での脆弱性 46 知らなかったし、 実際作ってしまっていた
  47. Blade + Vue.js での脆弱性 • mustache injection 対策案1 (不採用) –

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

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

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

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

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

    は思ったより難しかった 52
  53. Vue.js は思ったより難しかった 53 • 開発を始める前は… – チームメンバーはみな jQuery に慣れ親しんで いる(特にベテラン)

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

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

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

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

    飛び地にできないの? モデルの値を変えてるは ずなのに反映されない… Bootstrap一緒に使いた いけどうまくいかない…
  58. Vue.js は思ったより難しかった 58 • 調べながら実装を進める… 内部の要素はコンポーネントを 作ってそれで置き換えましょう Vue インスタンス入れ子 にしたいんだけど…

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

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

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

    ずなのに反映されない…
  62. Vue.js は思ったより難しかった 62 • jQuery 脳からのパラダイムシフトが必要? – 「jQuery でなら作り方わかってるのに」 –

    利き手でない方の手で字を書くかのよう… – 結局慣れるしかない • jQuery 系ライブラリとの相性 – ノウハウの蓄積が必要
  63. Vue.js は思ったより難しかった 63 • やっぱりちゃんと勉強しないとだめだった – 学習資料も限られていた – 最近は充実してきている •

    コンポーネントの理解は必須 – 分かりにくいとの声もあるが – そこは勉強してもらうしかない
  64. まとめ 64

  65. まとめ • フレームワークがスピード開発に役立った – ミドルウェアとの連携設定 – MVC の考えに沿ったソース配置 – ビジネスロジックへの集中ができた!

    • とくに Laravel で良かったこと – 豊富な機能 – 日本語公式ドキュメント – 活発なコミュニティ • 脆弱性への対応も早かった 65
  66. まとめ • Vue.js との組み合わせには注意 – 脆弱性への対応を後からするのは大変 • Vue.js もちゃんと勉強しよう –

    Vue.jsチュートリアル作成中… 66