Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

坂田晃平
February 16, 2019

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

坂田晃平

February 16, 2019
Tweet

More Decks by 坂田晃平

Other Decks in Technology

Transcript

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  5. はじめに
    4

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  16. なぜ Laravel を選択したか?
    16

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  30. Laravel で良かったこと
    30

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  36. Laravel で困ったこと
    36

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  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 になってるんやろ?

    View Slide

  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 になってるんやろ?
    実は、、、関係あった!
    (調べてよかった…)

    View Slide

  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

    View Slide

  43. • Bladeと Vue.js の組み合わせで起こる XSS
    サーバーでの処理 ブラウザでの処理
    Blade + Vue.js での脆弱性

    {{ $name }}

    sample.blade.php
    Blade で処理
    $name = “{{ alert(‘XSS') }}”

    {{ alert('XSS') }}


    {{ alert(‘XSS’) }}

    Vue.js が処理


    43
    {{ … }} の中の
    スクリプトが実行
    される!
    処理済みのHTMLデータ
    レスポンス送信
    ブラウザが読込

    View Slide

  44. • Bladeと Vue.js の組み合わせで起こる XSS
    サーバーでの処理 ブラウザでの処理
    Blade + Vue.js での脆弱性

    {{ $name }}

    sample.blade.php
    Blade で処理
    $name = “{{ alert(‘XSS') }}”

    {{ alert('XSS') }}


    {{ alert(‘XSS’) }}

    Vue.js が処理


    44
    {{ … }} の中の
    スクリプトが実行
    される!
    処理済みのHTMLデータ
    レスポンス送信
    ブラウザが読込

    View Slide

  45. • Blade と Vue.js の組み合わせで起こる XSS
    – Vue.js で処理される領域にユーザー入力の文字
    列をサーバー処理で埋め込むと危険
    – “mustache injection” と(個人的に)呼んで

    {{…}} ← これを Mustache 構文と呼ぶことから
    – 知らなかったら普通に作ってしまいそう
    Blade + Vue.js での脆弱性
    45

    View Slide

  46. • Blade と Vue.js の組み合わせで起こる XSS
    – Vue.js で処理される領域にユーザー入力の文字
    列をサーバー処理で埋め込むと危険
    – “mustache injection” と(個人的に)呼んで

    {{…}} ← これを Mustache 構文と呼ぶことから
    – 知らなかったら普通に作ってしまいそう
    Blade + Vue.js での脆弱性
    46
    知らなかったし、
    実際作ってしまっていた

    View Slide

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

    {{ alert('XSS') }}


    {{ escapeMustache($name) }}

    sample2.blade.php
    ブラウザでの処理

    {{ alert(‘XSS’) }}

    $name = “{{ alert(‘XSS') }}”

    View Slide

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

    {{ alert(‘XSS’) }}

    v-pre の要素内は Vue.js
    で処理されない

    View Slide

  49. Blade + Vue.js での脆弱性
    • mustache injection 対策案3 (採用)
    – “{{” や “}}” の文字間に半角空白を挿入する
    • “{” や “}” のHTMLエンティティ表現に対しても同様
    に処理が必要

    • “{”、“{”、“{” のうち 2 つの組み合わせ
    • “}”、“}”、“}” のうち 2 つの組み合わせ
    • さらにそれらが連続している場合でも漏れなく空白を
    入れる必要がある
    49
    サーバーでの処理
    {{{{{ … }}}}}
    危険な文字列:
    { { { { { … } } } } }
    無害な文字列:

    View Slide

  50. Blade (SSR) + Vue.js での脆弱性
    • mustache injection 対策案 (3)
    – “{{” や “}}” の文字間に半角空白を挿入する
    • “{” や “}” のエンティティ表現に対しても同様に処理
    が必要

    • “{”、“{”、“{” のうち 2 つの組み合わせ
    • “}”、“}”、“}” のうち 2 つの組み合わせ
    • さらにそれらが連続している場合でも漏れなく空白を
    入れる必要がある
    50
    サーバーでの処理
    {{{{{ … }}}}}
    危険な文字列:
    { { { { { … } } } } }
    無害な文字列:
    $replacementMap = [
    "{{" => "{ {"
    , "{{" => "{ {"
    , "{{" => "{ {"
    , "{{" => "{ {"
    , "{{" => "{ {"
    , "{{" => "{ {"
    , "{{" => "{ {"
    , "{{" => "{ {"
    , "{{" => "{ {"
    , "}}" => "} }"
    , "}}" => "} }"
    , "}}" => "} }"
    , "}}" => "} }"
    , "}}" => "} }"
    , "}}" => "} }"
    , "}}" => "} }"
    , "}}" => "} }"
    , "}}" => "} }"
    ];

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  64. まとめ
    64

    View Slide

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

    View Slide

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

    View Slide