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

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

akatsukinewgrad
December 17, 2021
940

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

akatsukinewgrad

December 17, 2021
Tweet

More Decks by akatsukinewgrad

Transcript

  1. 自己紹介 - otofune と言います - github.com/otofune - twitter.com/otofune418 - 9月に株式会社アカツキ

    ATLAS チームでインターン - その際の記録はこちら https://hackerslab.aktsk.jp/2021/10/19/185139 - 今日はブラウザ拡張を作ってみた話をします 2
  2. Google アカウントへの複数同時ログイン - Google アカウントには同時にログインすることができて、切り替えて 各種サービスを使うことができる - Web でこの仕組みを作るのはすごい -

    https://support.google.com/accounts/answer/1721977 - 始めにログインしたアカウントがデフォルトアカウントとなって、 新しく開いたときにはデフォルトアカウントが使われる - 直近使っていたものとかを記憶してくれない - 必要ならそこからUIを切り替える必要がある - ?authuser=<n> という query string を付けることで、開くときに指定することもできる 4
  3. 同時ログインの問題点: リンクの共有 - 人と一緒になにかやるとき、いろいろなファイルやらを共有したくなる - Google Drive のファイル - Google

    Cloud のリンク - BigQuery のクエリやモニタリングページ - Google Drive のファイルは適切なアカウントを選んでくれる - (フォルダはしてくれない ) - Google Cloud はそうではなく、デフォルトアカウントで開いてしまい 権限不足のエラーが出ることになる 6
  4. 問題の解決法 - デフォルトアカウントを合わせる: Chrome を使いプロファイルを分ける - リンクを開くときは直近のウィンドウで開くので誤ったプロファイルで開いてしまう 可能性がある - 人間が機能の不足を補うのは面倒

    - メインブラウザが Chrome ではないとつらい - Google Cloud Console を拡張する: 自動で適切なアカウントが 選択されるようにする 8 今回は拡張するアプローチを取ってみる
  5. Webページを拡張する方法たち - Bookmarklet - ブックマークに `javascript:alert(1)` のようにコードを入れて、適宜実行するもの - 一度きりならいいが、今回は自動で実行してほしいので合わない -

    User script - ブラウザごとに拡張機能の作り方が別れていたころに誕生した、簡単な JavaScript のコードを 書くだけで拡張できる仕組み - Greasemonkey が走りだが、実行環境は他のブラウザにも移植されている - スクリプトを実行するための拡張機能をインストールする必要がある - 当然バグと付き合う必要がある - 必要ないなら余計なものは入れたくない 10
  6. Webページを拡張する方法たち - Web Extension - Chrome のブラウザ拡張をベースとして、標準化が進んでいるもの - Mozilla, Opera,

    Microsoft がやっていたらしい https://wiki.mozilla.org/WebExtensions/Spec - Chromium 系列は当然のこと、Firefox や Safari も同じコードを書けばクロスブラウザで 動くようになる… かもしれない - 現時点では非互換な部分がいくつかあり polyfill が必要なこともある 11
  7. 自動で適切なアカウントを選択するには 12 - Google Cloud Console の URL には Project

    ID が `?project=` という クエリ文字列として与えられることはわかっている - Google サービス全般の動きとして URL に `?authuser=<n>` という クエリをつけるとアカウントが切り変わることもわかっている - 実際にアカウントを切り替えるとこのクエリがついていることを確認できる - n はアカウントにログインした順 (1-indexed) - アカウント一覧をどこかから取ってきて、なんらかの方法で プロジェクトへのアクセス権をチェックして、適切な URL に リダイレクトすればよい
  8. 調査 - まずは HTML や JS を読まないでできるところから - 開発者コンソールでネットワークの様子を確かめてみる -

    存在しない Project ID を URL に入れたら 404 が返ってくるか? - 伝統的なサーバーサイドアプリケーション (MPA) か、あるいは SPA か - メニューからプロジェクトを切り替えたらどんなことが起きるか ? 13
  9. 調査 - どんなクエリを付けてもダッシュボードは常に 200 OK → SPA - アカウント一覧のデータは XHR/Fetch

    の呼び出しにはないが、 アカウント切り替えメニューが表示されているのでどこかに データがありそう - プロジェクト情報を取得する API がわかった - Cookie をつけて authuser を指定すれば実行できる - 404, 403 (権限不足), 401 (再ログインが必要), 200 とステータスコードを返してくれる - ステータスコードを見るだけで簡単にチェックできそう 14
  10. 拡張機能を実装する - WebExtensions を使う - JavaScript から WebExtensions API を通じてブラウザを操作できる拡張の仕様

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

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

    Worker みたいなもの - コンテンツスクリプト - 直接ページの内容を操作 - DOM API が使える - ブラウザのメニューやツールバーへの干渉 - 詳しくは MDN を見てください https://developer.mozilla.org/ja/docs/Mozilla/Add-ons/WebExtensions 21
  13. WebExtensions の開発環境を整える - できれば TypeScript で書きたい - そして Web Extension

    APIs にも型がつくとうれしい - クロスブラウザでも全く同じコードで書けるとうれしい - 設定ファイルである manifest.json のチェックも軽くしてほしい 22
  14. 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
  15. コンテンツスクリプトのハマりどころ: isolation - WebExtension のスクリプトはサイト上で動作するページスクリプトと 異なり特権的な扱いを受ける - たとえば CORS を無視してリクエストができる

    - そのため、コンテンツスクリプトからは直接ページスクリプトと データのやりとりができないようになっている - 今回の用途では WebExtension API へのアクセスや特権的な地位は 不要なので script タグを挿入して、ページスクリプトにすることで対処 24
  16. +α: 作ったからには広く使える状態にしたい - ブラウザ拡張は野良ではほぼインストールできないと言っても 過言ではない (about:config などで設定を変更しないといけない) → ストアに出す必要がある -

    実装よりも公開の準備のほうが時間がかかった - アイコンを用意する必要がある - 今回は Flaticon の素材をそのまま使っている - スクリーンショットが必要 - リダイレクトするだけなのでどういうものを 用意したものか困った - Skitch で適当にラクガキして出した - 拡張がなぜその権限を必要としているか などをしたためる必要がある - どのストアにも審査があり、LTには間に合わず 29
  17. まとめ - WebExtensions を使えばクロスブラウザで動作する拡張機能が書ける - 実装例として Google Cloud の拡張をどう実装したか紹介した -

    広く使える状態にするにはストアへの公開が必要で、そこはハードル - その点では Userscript に分がある 30