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

WebExtensions の力で_不満を解消したい!_Google Cloud編

akatsukinewgrad
December 17, 2021
790

WebExtensions の力で_不満を解消したい!_Google Cloud編

akatsukinewgrad

December 17, 2021
Tweet

Transcript

  1. WebExtensions の力で
    不満を解消したい!
    Google Cloud 編
    otofune
    1

    View full-size slide

  2. 自己紹介
    - otofune と言います
    - github.com/otofune
    - twitter.com/otofune418
    - 9月に株式会社アカツキ ATLAS チームでインターン
    - その際の記録はこちら https://hackerslab.aktsk.jp/2021/10/19/185139
    - 今日はブラウザ拡張を作ってみた話をします
    2

    View full-size slide

  3. 突然ですが
    Google のサービス、使ってますか?
    3

    View full-size slide

  4. Google アカウントへの複数同時ログイン
    - Google アカウントには同時にログインすることができて、切り替えて
    各種サービスを使うことができる
    - Web でこの仕組みを作るのはすごい
    - https://support.google.com/accounts/answer/1721977
    - 始めにログインしたアカウントがデフォルトアカウントとなって、
    新しく開いたときにはデフォルトアカウントが使われる
    - 直近使っていたものとかを記憶してくれない
    - 必要ならそこからUIを切り替える必要がある
    - ?authuser= という query string を付けることで、開くときに指定することもできる
    4

    View full-size slide

  5. Google アカウントへの複数同時ログイン
    5
    アカウント切り替えメニュー

    View full-size slide

  6. 同時ログインの問題点: リンクの共有
    - 人と一緒になにかやるとき、いろいろなファイルやらを共有したくなる
    - Google Drive のファイル
    - Google Cloud のリンク - BigQuery のクエリやモニタリングページ
    - Google Drive のファイルは適切なアカウントを選んでくれる
    - (フォルダはしてくれない )
    - Google Cloud はそうではなく、デフォルトアカウントで開いてしまい
    権限不足のエラーが出ることになる
    6

    View full-size slide

  7. 問題の解決法
    - デフォルトアカウントを合わせる: Chrome を使いプロファイルを分ける
    - リンクを開くときは直近のウィンドウで開くので誤ったプロファイルで開いてしまう
    可能性がある
    - 人間が機能の不足を補うのは面倒
    - メインブラウザが Chrome ではないとつらい
    - Google Cloud Console を拡張する: 自動で適切なアカウントが
    選択されるようにする
    7

    View full-size slide

  8. 問題の解決法
    - デフォルトアカウントを合わせる: Chrome を使いプロファイルを分ける
    - リンクを開くときは直近のウィンドウで開くので誤ったプロファイルで開いてしまう
    可能性がある
    - 人間が機能の不足を補うのは面倒
    - メインブラウザが Chrome ではないとつらい
    - Google Cloud Console を拡張する: 自動で適切なアカウントが
    選択されるようにする
    8
    今回は拡張するアプローチを取ってみる

    View full-size slide

  9. Google Cloud を拡張する
    9

    View full-size slide

  10. Webページを拡張する方法たち
    - Bookmarklet
    - ブックマークに `javascript:alert(1)` のようにコードを入れて、適宜実行するもの
    - 一度きりならいいが、今回は自動で実行してほしいので合わない
    - User script
    - ブラウザごとに拡張機能の作り方が別れていたころに誕生した、簡単な JavaScript のコードを
    書くだけで拡張できる仕組み
    - Greasemonkey が走りだが、実行環境は他のブラウザにも移植されている
    - スクリプトを実行するための拡張機能をインストールする必要がある
    - 当然バグと付き合う必要がある
    - 必要ないなら余計なものは入れたくない
    10

    View full-size slide

  11. Webページを拡張する方法たち
    - Web Extension
    - Chrome のブラウザ拡張をベースとして、標準化が進んでいるもの
    - Mozilla, Opera, Microsoft がやっていたらしい
    https://wiki.mozilla.org/WebExtensions/Spec
    - Chromium 系列は当然のこと、Firefox や Safari も同じコードを書けばクロスブラウザで
    動くようになる… かもしれない
    - 現時点では非互換な部分がいくつかあり polyfill が必要なこともある
    11

    View full-size slide

  12. 自動で適切なアカウントを選択するには
    12
    - Google Cloud Console の URL には Project ID が `?project=` という
    クエリ文字列として与えられることはわかっている
    - Google サービス全般の動きとして URL に `?authuser=` という
    クエリをつけるとアカウントが切り変わることもわかっている
    - 実際にアカウントを切り替えるとこのクエリがついていることを確認できる
    - n はアカウントにログインした順 (1-indexed)
    - アカウント一覧をどこかから取ってきて、なんらかの方法で
    プロジェクトへのアクセス権をチェックして、適切な URL に
    リダイレクトすればよい

    View full-size slide

  13. 調査
    - まずは HTML や JS を読まないでできるところから
    - 開発者コンソールでネットワークの様子を確かめてみる
    - 存在しない Project ID を URL に入れたら 404 が返ってくるか?
    - 伝統的なサーバーサイドアプリケーション (MPA) か、あるいは SPA か
    - メニューからプロジェクトを切り替えたらどんなことが起きるか ?
    13

    View full-size slide

  14. 調査
    - どんなクエリを付けてもダッシュボードは常に 200 OK → SPA
    - アカウント一覧のデータは XHR/Fetch の呼び出しにはないが、
    アカウント切り替えメニューが表示されているのでどこかに
    データがありそう
    - プロジェクト情報を取得する API がわかった
    - Cookie をつけて authuser を指定すれば実行できる
    - 404, 403 (権限不足), 401 (再ログインが必要), 200 とステータスコードを返してくれる
    - ステータスコードを見るだけで簡単にチェックできそう
    14

    View full-size slide

  15. 調査
    - アカウント切り替えメニューのデータはどこから来るのか?
    - API 呼び出しでないなら、 Cookie だったり
    HTML 内だったりに埋め込まれていると
    予想できる
    15

    View full-size slide

  16. 調査
    - HTMLをメールアドレスで検索したところ script タグ内に `var
    pantheon_account_data` として挿入されていることがわかった
    - 画像の通り [5] に同時にログインしているアカウントの一覧が入っている
    16

    View full-size slide

  17. 拡張機能の実装
    17

    View full-size slide

  18. 拡張機能を実装する
    - Google Cloud Console のページに定義されている `pantheon_account_data`
    が読めて、Cookie をつけてリクエストをし、
    適切にリダイレクトできればよい
    - ページ内に追加の JavaScript が挿入できれば、どんな仕組みでも OK
    18

    View full-size slide

  19. 拡張機能を実装する
    - WebExtensions を使う
    - JavaScript から WebExtensions API を通じてブラウザを操作できる拡張の仕様
    - 実装に差異はあるものの、ほとんどのブラウザが直接対応しているというのが嬉しい
    - Chrome 拡張機能の仕様を下敷きに、その他のベンダーでも使えるように標準化が
    進められている
    - Mozilla (Firefox) が lead しており、2020年には Apple も WebExtensions を
    Safari 拡張に変換するツールを公開するなどクロスブラウザーで
    使える技術になってきている
    → Chrome, Firefox, Edge, Safari で動作する
    - User script は実行環境として拡張機能を入れないといけない点が微妙
    - なにより MDN に情報がまとまっていると嬉しい
    19

    View full-size slide

  20. WebExtensions でできること
    - スクリプトの追加
    - バックグラウンドスクリプト
    - 通信の置き換え
    - Service Worker みたいなもの
    - コンテンツスクリプト
    - 直接ページの内容を操作
    - DOM API が使える
    - ブラウザのメニューやツールバーへの干渉
    - 詳しくは MDN を見てください
    https://developer.mozilla.org/ja/docs/Mozilla/Add-ons/WebExtensions
    20

    View full-size slide

  21. WebExtensions でできること
    - スクリプトの追加
    - バックグラウンドスクリプト
    - 通信の置き換えなど
    - Service Worker みたいなもの
    - コンテンツスクリプト
    - 直接ページの内容を操作
    - DOM API が使える
    - ブラウザのメニューやツールバーへの干渉
    - 詳しくは MDN を見てください
    https://developer.mozilla.org/ja/docs/Mozilla/Add-ons/WebExtensions
    21

    View full-size slide

  22. WebExtensions の開発環境を整える
    - できれば TypeScript で書きたい
    - そして Web Extension APIs にも型がつくとうれしい
    - クロスブラウザでも全く同じコードで書けるとうれしい
    - 設定ファイルである manifest.json のチェックも軽くしてほしい
    22

    View full-size slide

  23. WebExtensions の開発環境を整える
    - バンドラーとして @parcel/config-webextension を使う
    - https://parceljs.org/recipes/web-extension
    - manifest.json を見て必要なファイルを dist にコピーしてくれる
    - 直接 manifest.json に ts ファイルを指定すればトランスパイルしてくれる
    - ライブラリとして webextension-polyfill を使う
    - Chrome 拡張の `chrome` API を Web Extension の `browser` API に変換してくれる
    - このライブラリ向けの型定義として @types/webextension-polyfill があり、型がつく
    23

    View full-size slide

  24. コンテンツスクリプトのハマりどころ: isolation
    - WebExtension のスクリプトはサイト上で動作するページスクリプトと
    異なり特権的な扱いを受ける
    - たとえば CORS を無視してリクエストができる
    - そのため、コンテンツスクリプトからは直接ページスクリプトと
    データのやりとりができないようになっている
    - 今回の用途では WebExtension API へのアクセスや特権的な地位は
    不要なので script タグを挿入して、ページスクリプトにすることで対処
    24

    View full-size slide

  25. できたもの
    25
    https://github.com/otofune/webext-auto-account-switcher-for-gcloud
    調査は計2時間くらい
    実装は計3時間くらい
    Firefox, Chrome で動作

    View full-size slide

  26. できたもの
    26
    https://github.com/otofune/webext-auto-account-switcher-for-gcloud
    調査は計2時間くらい
    実装は計3時間くらい
    Firefox, Chrome で動作

    View full-size slide

  27. できたもの
    27
    https://github.com/otofune/webext-auto-account-switcher-for-gcloud
    調査は計2時間くらい
    実装は計3時間くらい
    Firefox, Chrome で動作

    View full-size slide

  28. できたもの
    28
    https://github.com/otofune/webext-auto-account-switcher-for-gcloud
    調査は計2時間くらい
    実装は計3時間くらい
    Firefox, Chrome で動作

    View full-size slide

  29. +α: 作ったからには広く使える状態にしたい
    - ブラウザ拡張は野良ではほぼインストールできないと言っても
    過言ではない (about:config などで設定を変更しないといけない)
    → ストアに出す必要がある
    - 実装よりも公開の準備のほうが時間がかかった
    - アイコンを用意する必要がある
    - 今回は Flaticon の素材をそのまま使っている
    - スクリーンショットが必要
    - リダイレクトするだけなのでどういうものを
    用意したものか困った
    - Skitch で適当にラクガキして出した
    - 拡張がなぜその権限を必要としているか
    などをしたためる必要がある
    - どのストアにも審査があり、LTには間に合わず 29

    View full-size slide

  30. まとめ
    - WebExtensions を使えばクロスブラウザで動作する拡張機能が書ける
    - 実装例として Google Cloud の拡張をどう実装したか紹介した
    - 広く使える状態にするにはストアへの公開が必要で、そこはハードル
    - その点では Userscript に分がある
    30

    View full-size slide

  31. ぜひ拡張機能を作って
    快適なブラウジングライフを!
    31

    View full-size slide