Slide 1

Slide 1 text

1 ブラウザストレージを活⽤した、 複数アプリをまたぐ永続化とリアクティブな同期 てつを。(@tetsuwo0717)

Slide 2

Slide 2 text

2 ⾃⼰紹介 GMOペパボ株式会社 事業開発部 Alive Projectチーム てつを。 ‧出⾝地/勤務地:⿅児島⛰ ‧X:@tetsuwo0717

Slide 3

Slide 3 text

1. ブラウザストレージについて 2. Alive Studio のブラウザストレージ活⽤について a. OBS 内での動作 b. localStorage+イベントでの同期 3. 注意点 a. セキュリティ b. イベントハンドラの氾濫と抽象化 c. 型安全性 4. まとめ ⽬次 3 ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期

Slide 4

Slide 4 text

4 ブラウザストレージについて

Slide 5

Slide 5 text

ブラウザストレージを活⽤した、 複数アプリをまたぐ永続化と リアクティブな同期

Slide 6

Slide 6 text

Browser storage ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 ブラウザに内蔵されているデータを保存する仕組み。 ・localStorage ・Session storage ・indexedDB ・Cookies ・Cache storage ・その他

Slide 7

Slide 7 text

Browser storage ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 ・localStorage ・Session storage ・indexedDB ・Cookies ・Cache storage ・その他 (標準化されていない 各Browserが独自に持つstorageなど)

Slide 8

Slide 8 text

Browser storage ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 Web storage ・localStorage ・Session storage ・indexedDB ・Cookies ・Cache storage ・その他 (標準化されていない 各Browserが独自に持つstorageなど)

Slide 9

Slide 9 text

localStorage ・ブラウザに key/value形式でデータを永続的に保存 できる仕組み。 ・保存容量は Cookie より大きい(ブラウザによって数MB〜10MB程度) ・ブラウザを閉じてもデータは残る(ユーザーが削除するかブラウザのストレージをクリアしない限り保 持)。 ・同一オリジン (同じスキーム(https)、ホスト名(hoge.com)、ポート(:431))で共有される ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage

Slide 10

Slide 10 text

Session storage ・ブラウザに key/value形式でデータを一時的に保存 できる仕組み。 ・保存容量は Cookie より大きい(ブラウザによって数MB〜10MB程度) ・ページセッションの寿命が尽きると消える(タブやウィンドウを閉じると削除)。 ・タブ/ウィンドウごとに独立。 ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage

Slide 11

Slide 11 text

IndexedDB ・ブラウザに 構造化データを保存 できるデータベース。 ・オブジェクトストアと呼ばれる仕組みで、オブジェクトやファイル、バイナリデータまで保存可能。 ・容量は localStorage より大きい(数百MB〜数GBまでブラウザ依存)。 ・データはユーザーが削除しない限り保持される(ブラウザを閉じても残る)。 ・同一オリジンで共有。 ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API

Slide 12

Slide 12 text

12 Alive Studio の localStorage活⽤について

Slide 13

Slide 13 text

Alive Studio ・Vtuberを始めとするライブ配信者向けの配信画面デザインツール。 ・OBS上で動く → OBS・・・配信者がオンライン配信や録画を行うためのソフト ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期

Slide 14

Slide 14 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期

Slide 15

Slide 15 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 配信画面 Alive Studio

Slide 16

Slide 16 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期

Slide 17

Slide 17 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期

Slide 18

Slide 18 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 どうやっているの…?

Slide 19

Slide 19 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 OBSには配信画面にブラウザ(CEF)を表示する機能がある

Slide 20

Slide 20 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 OBSには配信画面にブラウザを表示する機能がある →配信画面上でブラウザを表示したい時に便利 https://www.youtube.com/@cleha_blood

Slide 21

Slide 21 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 AliveStudioのセットアップ時に追加される「ソース」も 全てブラウザ

Slide 22

Slide 22 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 画像を表示するだけのアプリ

Slide 23

Slide 23 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 画像を表示するだけのアプリ

Slide 24

Slide 24 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 背景を透過することで、まるで素材を追加したかのように見える

Slide 25

Slide 25 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期

Slide 26

Slide 26 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 ?

Slide 27

Slide 27 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 これもブラウザ

Slide 28

Slide 28 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 これもブラウザ

Slide 29

Slide 29 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 OBSのプラグインを作っているんですね〜!

Slide 30

Slide 30 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 OBSのプラグインを作っているんですね〜! Webアプリを表示しているだけ

Slide 31

Slide 31 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 ブラウザ内のドキュメント間の同期について

Slide 32

Slide 32 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 ・「localStorage」を使って同期している  → 同一originであるため共有される ・ブラウザドックからlocalStorageに「これをここに表示」という情報を書き込む localStorage これをここのソースに 表示するんや! 👁 storageEventを監視 →画像の変更など ドキュメント間の同期について

Slide 33

Slide 33 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 localStorage これここのソースに 表示するんや! 👁 StorageEventを監視 →画像の変更など ドキュメント間の同期について

Slide 34

Slide 34 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 localStorage これここのソースに 表示するんや! 👁 StorageEventを受け取って →画像の変更など ドキュメント間の同期について

Slide 35

Slide 35 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 ドキュメント間の同期について ドキュメント間のリアクティブな同期が可能になる

Slide 36

Slide 36 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 ドキュメント間の同期について ドキュメント間のリアクティブな同期が可能になる

Slide 37

Slide 37 text

37 localStorageのイベントについて

Slide 38

Slide 38 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 localStorageのイベントについて ・localStorageのイベントは、同じタブでは発火しない

Slide 39

Slide 39 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 localStorageのイベントについて ・localStorageのイベントは、同じタブでは発火しない https://developer.mozilla.org/en-US/docs/Web/API/Window/storage_event     TabA TabB 同origin localStorage

Slide 40

Slide 40 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 localStorageのイベントについて ・localStorageのイベントは、同じタブでは発火しない https://developer.mozilla.org/en-US/docs/Web/API/Window/storage_event     TabA TabB storageEventを期待し ているコンポーネント storageEventを期待し ているコンポーネント localstorageに対して更新を行うコ ンポーネント 👁 👁 localStorage

Slide 41

Slide 41 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 localStorageのイベントについて ・localStorageのイベントは、同じタブでは発火しない https://developer.mozilla.org/en-US/docs/Web/API/Window/storage_event     TabA TabB storageEventを期待し ているコンポーネント storageEventを期待し ているコンポーネント localstorageに対して更新を行うコ ンポーネント write 👁 👁 localStorage

Slide 42

Slide 42 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 localStorageのイベントについて ・localStorageのイベントは、同じタブでは発火しない https://developer.mozilla.org/en-US/docs/Web/API/Window/storage_event     TabA TabB storageEventを期待し ているコンポーネント storageEventを期待し ているコンポーネント localstorageに対して更新を行うコ ンポーネント write 👁 👁 piyoKey:hoge piyoKey:fuga localStorage

Slide 43

Slide 43 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 localStorageのイベントについて ・localStorageのイベントは、同じタブでは発火しない https://developer.mozilla.org/en-US/docs/Web/API/Window/storage_event     TabA TabB storageEventを期待し ているコンポーネント storageEventを期待し ているコンポーネント localstorageに対して更新を行うコ ンポーネント write 👁 👁 event event localStorage

Slide 44

Slide 44 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 localStorageのイベントについて ・localStorageのイベントは、同じタブでは発火しない https://developer.mozilla.org/en-US/docs/Web/API/Window/storage_event     TabA TabB storageEventを期待し ているコンポーネント storageEventを期待し ているコンポーネント localstorageに対して更新を行うコ ンポーネント write 👁 👁 event event localStorage

Slide 45

Slide 45 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 localStorageのイベントについて ・storage イベントオブジェクトには oldValue と newValue プロパティが含まれている ・keyの検証をすれば localStorage.getItem() を再度呼び出す必要はない。

Slide 46

Slide 46 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 localStorage超便利じゃん!!

Slide 47

Slide 47 text

47 localStorageを扱う上で⾒えてきた課題と注意点

Slide 48

Slide 48 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 1.セキュリティ ・localStorage は任意のスクリプトから参照可能 → XSS による情報漏洩のリスク ・localStorage の値はユーザー側で改変可能 → データの完全性を保証できないリスク https://raxis.com/blog/dangers-of-storing-sensitive-data-in-web-storage/ https://www.rdegges.com/2018/please-stop-using-local-storage/

Slide 49

Slide 49 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 1.セキュリティ https://raxis.com/blog/dangers-of-storing-sensitive-data-in-web-storage/ ・localStorage は任意のスクリプトから参照可能 → XSS による情報漏洩のリスク ・localStorage の値はユーザー側で改変可能 → データの完全性を保証できないリスク そもそも機密性の高いデータは localStorage に保存しない。 「消えても問題ない情報」「漏洩しても問題ない情報」のみ保存するようにする。 ⭐サーバー側で使用するときは保存された localStorageの値は基本「信用しない」。 サーバー側で検証/認証を行う。

Slide 50

Slide 50 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 2.イベントハンドラの増殖 ・localStorageごとに storage イベントや独自のハンドラが生える。 ・結果として、コードのあちこちに似たようなイベント処理が散らばり、複数のハンドラが非同期に作用し合うた めテストが書きづらくなり、検証やデバッグのコストが大きくなる。 localStorage component A component B component C event event event 地獄!!😱

Slide 51

Slide 51 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 2.イベントハンドラの増殖 ・図(例) 各コンポーネントからの 依存をHooksに集約し、Hooksで呼び出すlocalStorageへの依存を外部から注入 す ることでテストが可能になり、 eventの受け取りも単純化  localStorage component A component B component C Hooks Utility Utility(mock) DI DI event →テストが書ける

Slide 52

Slide 52 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 3.型安全性 ・localStorage の値は すべて string 型 ・ユーザーが自由に値を変更可能(先述) ・localStorage の値は すべて string 型 → 型の保証がない ・ユーザーが自由に値を変更可能(先述) → 期待する構造・型で取り出せる保証がない

Slide 53

Slide 53 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 3.型安全性 ・localStorage の値は すべて string 型 → 型の保証がない ・ユーザーが自由に値を変更可能(先述) → 期待する構造・型で取り出せる保証がない parse + validation を組み合わせて型安全に

Slide 54

Slide 54 text

ブラウザストレージを活⽤した、複数アプリをまたぐ永続化とリアクティブな同期 まとめ localStorage と storage イベントを組み合わせると、クロスタブ間でリアクティブな同期ができる ・しかし利用には セキュリティ・型安全性・保守性 に注意が必要 localStorage の利用指針 ・機密性の高い情報は保存しない ・保存するのは「消えても困らない」「漏洩しても困らない」情報だけ ・サーバー側で扱う時には検証/認証 実装上 ・イベントハンドラの増殖 → 抽象化・依存性を外から注入することでテストを書く ・型安全性 → Zod 等で 安全にparse + validate

Slide 55

Slide 55 text

55 Thank you!