ブログとか
ブログとか
2025-06-19
サイトのURLは pk.urtell.com 。
パスキーは、パスワードの代わりに生体認証やセキュリティキーを使ってログインする仕組みで、WebAuthn という Web 標準技術を使っている。
WebAuthn を使ったパスキー認証のデモサイトを作った。実際にパスキーでの登録・ログインを体験できる。
ほぼClaudeCodeに書かせた。
途中でいろいろ飽きて、テーマを切り替えられるようにしたり、多言語対応にしたりした。
ClaudeCodeに書かせるので、ライブラリの使い方を自分で調べる必要が無いので、あえてRustやSolidJSを使った。
Rustに関しては、結構ライブラリがあっていい感じではあるが、Goと比べるとどうしてもプロダクションビルドは結構時間がかかると思った。
どうせアクセスは少ないので、サーバーは AWS Lambda を使ってサーバーレスにした。 フロントエンドは CloudFront + S3 で静的ホスティング。 NeonDBは無料で使える。
GHA で CI/CD もやってみたけど、遅いし、個人だと無駄にコストがかかることに気づいてやめた。
最初に書いたローカル用デプロイスクリプトのほうが速いし、コストもかからなくて良い。
GHA使わない代わりに、precommit、prepushのhookでformat、lint、自動テスト実行を実行させるようにした。 AIが勝手にやばいコードをcommit, push するのを防ぐ意味でもローカルチェックは有効だと思う。
登録時:
ログイン時:
-- ユーザーテーブル
users (
id, username, display_name, role, created_at, updated_at
)
-- 認証情報テーブル
credentials (
id, user_id, credential_id, public_key, counter,
transports, backup_eligible, backup_state,
device_name, created_at, last_used_at
)
-- セッションテーブル(登録フロー用)
sessions (
session_id, user_id, challenge, state, expires_at
)
フロントエンドは、無駄に SolidJS を使い、コンポーネントベースで実装している。というか、AIが殴り書いたコードをコンポーネントに分割させるという流れで実装することが多かった。Tailwind CSS でスタイリングしたが、途中で飽きてきて、いろんなテーマを切り替えられるようにした。
多言語対応は i18n システムを自前実装。ロケールファイルを動的にインポートしている。
WebAuthn を使ったパスキー認証は、実装してみると意外とシンプルだった。ブラウザと認証器がほとんどの処理を担当してくれるため、サーバー側は公開鍵の保存と検証だけである。
パスワード認証に比べて、フィッシング耐性があり、ユーザーも覚える必要がないため、今後普及していくと思われる。