ジンジャー研究室

長めのつぶやき。難しいことは書きません。

Deno Deploy で WebAuthn を使ったサイトを作ってみた

作ったもの

Kaleidoshare という、オンライン万華鏡を作って共有できるサービスを作ってみた!

kaleidoshare.deno.dev

コードはここ。

github.com

作品は Twitter で公開できる。

まだまだ粗い部分が多いのだが、そもそもの目的が技術検証なのでまあこのくらいの完成度で良いでしょうということで(メンテするのがめんどくさい)。でも面白いと思ったら試してみてね。

動機

  • Deno Deploy は Cloudflare Workers のようにエッジに簡単にデプロイできるサービスの中でもパフォーマンスで群を抜いているらしく、以前から気になっていた。最近 Deno KV という分散ストレージが使えるようになったので試してみたい。
  • せっかくなので WebAuthn によるパスワードレス認証も試してみたい。最近はプラットフォームのパスキー対応が進んでいるのでデバイスを跨げるはず。
  • ついでに最近のフロントエンドのツールを色々キャチアップしたい。

この辺を満たす適当なお題を考えたところ、万華鏡に行き着いた。

サインアップ・ログイン体験

指紋認証でパスワード不要。最高。

サインアップ

ログイン

この例ではデバイスに保存しているけど、パスキーで登録すれば別のデバイスでもログインできる。

感想など

  • 開発時のコードがそのまま Deno Deploy 上でも動いて素晴らしい。サーバーレス環境で動くようにコアレベルで抽象化されていて、例えるなら express で作ったアプリが Lambda 上で動くような感じ。KV も LocalStorage くらいの手軽さで使えて面倒なセットアップが不要。
  • Deno 自体には慣れる必要がある。deno.json に import map を書く方法とか、エディタのプラグインの使い方とか(再起動・ライブラリのキャッシュが必要)。Node.js 互換は日が浅いので制限があり、例えば esm.sh を使うなどして回避する必要がある。最初は Vite も Deno で実行していたがバグがあったので諦めて Node.js に切り替えた。今後に期待。
  • Deno KV は value のサイズが 64KB に制限されており、作品ごとの OGP 画像がそのままでは保存できなかった。仕方がないので image uri を分割して保存して、取得時に結合して復元するということをした。あまり大きなデータの保存は想定されていないのかもしれない。
  • WebAuthn はクライアント側が簡単なので油断していたらサーバー側がしんどすぎたのでライブラリに頼った。とはいえフローは簡単で、サインアップ・ログイン共に「サーバーにリクエスト -> サーバーが生成した情報をブラウザに渡す -> ユーザーが認証ステップを踏む -> 結果をサーバーに返す -> サーバーで検証して情報を保存」をすればいい。
  • Playwright で WebAuthn を動作させるには Chromium で virtual authenticator を使う。ただしこの方法ではログイン時にユーザを指定しないと動作しなかったため、テスト時だけはサインアップの時と同じユーザー名をサーバーに送信するようにした。
  • まだまだベストプラクティスが分からない。パスキーはデバイスを跨げるがプラットフォーム(Apple, Google, Microsoft)は跨げない。一応それを考慮して複数のクレデンシャルを登録できるようにしてはみたが、そんな罠を知っているユーザーは稀なので不慮の事故が避けられない。復帰用にメールアドレスなどを登録した方が良いかも。

(Appendix) 要素技術一覧

想像以上に多岐に渡る技術をキャッチアップ出来て面白かった(本当は Deno Deploy や WebAuthn 以外にも色々工夫した部分を語りたいのだが、流石に話題がとっ散らかるので泣く泣く削った)。