📌

何も知らないpasskey認証の実装チュートリアルをchatgptに作成してもらったけどうまくいかなかった話

2024/12/26に公開

Commune Advent Calendarの21日目の記事です。今は既にクリスマスを終えた26日ですが...

前置き

年末年始でpasskeyに入門したいなーと思っていた折り、Advent Calendarイベントがちょうど余っていたので予定を早めChatGPT頼りに動くものを作ろうと思い立ちました。passkeyが雰囲気どんな仕組みなのか概念は知っていますが実装に関しては何も知らないところからスタートしてます。数時間プロンプトと格闘していましたが、エラー修正で埒が明かなかったり細かい修正で先祖返りしたコード提示されたりし、結局動くものはできませんでした。スッキリしなかったので年末年始にちゃんと入門しようという気持ちになれたので良かったことにします。
半年くらい前にも全てChatGPT頼りに動くものを作ろうとして失敗したので、個人的にはまだ使いたい技術のチュートリアルや関連ドキュメント読みながら進める方が早そうな印象を持っています。ですが世間の温度感的にはそんなことなさそうな気配があるため、何となく私のプロンプトとの対話力(要件整理と言語化力)が足りないだけな気もしてきています。その辺りの能力を養っていきたい。
以下格闘した記録です。

できたモノ

https://github.com/uewtwo/try-passkey-tutorial/tree/try-with-chatgpt

多分、"userIdをベースにchallengeを作成しフロント側で本人認証(ここでは指紋認証)、challengeの署名データをAPIリクエストに載せる"ところまで動いていそう。

プロンプトとの対話

スタートは良い

最初は、「passkeyによる認証を実装するチュートリアルを作成してください。typescript, nextを使ってください。DBはdockerで用意してください。」みたいなところから始めました。この時点でcreate-next-app/ライブラリのインストール/docker周り/DB(prisma)周り/indexページ/APIの口みたいな大体は良かったのですが、ユーザーが存在することが前提/challengeはどこからか降ってくる前提みたいな認識の齟齬がありました。
認証周りの実装は @simplewebauthn という提示されたパッケージを使って進行しました。

WebAuthn周りの苦闘

simplewebauthnではcredentialの作成に domain + userID を使うことでdiscoverableなcredentialを作成することが推奨されているっぽく
https://simplewebauthn.dev/docs/advanced/passkeys#server
ChatGPTもそんな感じのコードを出力してくれたのですが、このuserIDはUint8Array型である必要があり、ライブラリのXXX.d.tsファイル内にも定義として userID?: Uint8Array; と書かれているのですが、出力されたコードはstringの生userIDでした。「userIDはUint8Arrayです」みたいなことを書くとその回はエンコードしたコードを出力してくれるのですが、別の大きめな改修を依頼すると直ぐに生のuserIDを渡すコードに戻ってしまってました。
また、そのcredential含むoptionを生成する generateRegistrationOptions は非同期関数で定義されていますが、何かにつけて同期関数だからawait外しますという言葉と共にPromiseのままのoptionを扱うコードを生成してました。引数の渡し方もおかしかったので、もしかするとバージョン違いの問題かもしれない。
先祖返りする問題はコードの継ぎ足ししているターンと指示に対して一から出力内容作り直しているターンが有りそうで、条件として直近出力した同名ファイルのコードをベースに変更してくれ的な制約を最初に出しておけば解決しそうな気もしてきました。

その他良かった点

それっぽいフロント側のコード生成はかなり正確でした。「1つのページに登録と認証のボタンを用意してください。どちらもテキストフィールドに入力されたuserIdを使って対応するAPIを呼んでください。」みたいな雑なこと書いても動くものができてました。すごい。

感想

  • フロントエンドの見た目やシンプルなAPIリクエスト、サーバーエンドのAPIのガワやDBへの簡単な操作はかなり正確
  • 少し込み入ったライブラリはドキュメントないしサンプルコード見た方がまだ早いし楽
  • あまり知見のない技術のコードを出力されるとちょっとした修正でも脳の負荷が高い
  • Gihhubのレポジトリ全部食わせたLLMの話もあるけど、結局バージョン違いやそこまでサンプルの多くない領域はプロンプトと格闘する時間が無駄になりそう
  • 冒頭にも書いたけど、とはいえプロンプトとの対話力があればもう少しどうにかなりそうなのでまた数ヶ月後に挑戦したい

みたいなところで初回passkey入門失敗編は終わりにします、ケーキ食べて寝ます。

Discussion