Auth0 + Laravelで簡単Passkey実装

こんにちは！
社内でドキドキしながら「久しぶりにアドベントカレンダーするよ！」と言ったら、速攻で25日のカレンダーが埋まって一安心している株式会社Fusicの櫻川です。

この記事は[Fusic Advent Calendar 2023](https://qiita.com/advent-calendar/2023/fusic)の10日目の記事です。
この後もがっつりエンジニアからエンジニアではない人まで、様々な記事が上がってくるのでお楽しみ！

昨今の話題はChatGPTをはじめとする生成系AIでしょうか？
今回はChatGPTによって隠れてしまったけど、とても大事なPasskeyの実装について書いてみようと思います。

## Passkeyとは

すごくざっくり行ってしまうと生体認証などを活用してパスワードレス認証方式です。
ちょっと前に流行った、WebAuthnの改善版だと思ってください。

最近だと[GitHubがPasskeyに対応](https://github.blog/jp/2023-10-12-passkeys-are-generally-available/)したので話題になりましたね
それ以外にも様々なサイトがPasskeyに対応していってます。
- [Amazon](https://k-tai.watch.impress.co.jp/docs/news/1541516.html)
- [Google](https://k-tai.watch.impress.co.jp/docs/news/1538073.html)
- [docomo](https://www.docomo.ne.jp/info/notice/page/230308_00.html)
- [1password](https://www.publickey1.jp/blog/23/1password.html)

Passkeyの対応状況を確認できるサイトを1passwordがリリースしているので、日ごろ使っているサイトを調べてみてはいかがでしょうか？

https://passkeys.directory/

Passkeyに関しての詳しい話はネットで検索すると以下のような説明が大量に出てくるので、検索してみてください。
- [パスキー（Passkeys）ってなんだろう？（前編）](https://www.yubion.com/post/%E3%83%91%E3%82%B9%E3%82%AD%E3%83%BC%EF%BC%88passkeys%EF%BC%89%E3%81%A3%E3%81%A6%E3%81%AA%E3%82%93%E3%81%A0%E3%82%8D%E3%81%86%EF%BC%9F%EF%BC%88%E5%89%8D%E7%B7%A8%EF%BC%89)

Passkeyの分かりやすいメリットとすれば「指紋認証などを活用してパスワードを覚えずにログイン出来て楽」というものがあります。
また生体認証を活用するので「パスワードが漏洩したのでパスワードを変更しなきゃ」や「URLが1文字違うそっくりななフィッシングサイトに引っかかった」などに対策できるものと考えられます。

## Passkeyの実装

さて前段が長くなりましたが、Passkeyを自分で実装しようとするとJavaScriptを書いたり、サーバーサイドを書いたり、セキュリティを気にしたりと結構大変です。

なので今回はタイトルにもありますが、Auth0を利用してPasskeyを実装してみます。
とは言ってもほぼ何もすることなく実現できてしまいます。

### 1. Auth0のアカウント発行

まず、Auth0でアカウントを発行しましょう。
無料枠でも問題ありません。

https://auth0.com/jp/pricing

### 2. Auth0のログインフローを実装 (ID/passwordログイン)

Auth0は[様々なサンプル](https://auth0.com/docs/quickstart/webapp)が準備されています。
今回はLaravelを選択しました。
このチュートリアル通りにコマンドを実行してAuth0でのログインフローを設置します。

https://auth0.com/docs/quickstart/webapp/laravel/01-login

途中出てくる `callbacks` 等は自分の開発環境に合わせて修正してください。
また、localhostから変更したい場合は、合わせて.envの `APP_URL` も併せておいてください。

このチュートリアルを流して、 `http://example.com/login` にアクセスしてログイン画面が出ればOKです。
この時点では、まだPasskey未対応です。

### 3. Passkeyの有効化

現時点ではPasskeyを利用するようにできてないので有効化していきます。
有効化は以下の流れで行ってください。

1. Auth0にログインして、ダッシュボードへ
1. [Authentication]-[Database]に遷移
1. 対象のデータベースを選択
※対象のデータベースは、[Applications]-[Connections]で確認できます
1. [Authentication Methods]を選択

このタイミングで、以下の画面が表示されると思います。
基本的には、Passkeyと書かれているトグルを有効化するだけです。

![2023-12-10_10h28_30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49429/48532252-4b72-6f1c-ed7b-b261c7951b93.png)

ただし、有効化しようとすると以下のように画面が表示されると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49429/322b7e68-f331-0a56-989c-93d8764ee5b3.png)

Passkeyを有効化するには、全部の要件を満たす必要があるので、
Identifier First login flowに切り替えていきます。

### 4. Identifier First login flowへの切り替え

`Identifier First login flow` と書かれたリンクをクリックして、[Authentication Profile]に遷移します。

`Identifier First` を選んで、Saveを押してください
この切り替えによって、ログイン画面ではメールアドレスなどのユーザー識別子のみを求められる用になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49429/1c6012ac-d4db-1253-45b3-347ae56e5ed2.png)

ここまでくれば準備完了なので、「3. Passkeyの有効化」で書かれている有効化を行ってください.
以下のようにPasskeyが有効化できれば準備完了です:tada:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49429/85d5151c-afa0-ff90-3117-73bd6fc43813.png)

### 5. アクセスしてみる

`http://example.com/login` にアクセスしてみてください。
※URLは自身が設定したものでアクセスしてください。

#### 5.1 ログイン画面

パスキーを使用して続行するを押したくなりますが、まずはサインアップをしてください

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49429/f1bcca7a-99ed-ee71-f51c-94e1db4086d2.png)

#### 5.2 サインアップ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49429/d5e1ab03-d894-fd49-c9ea-a9920b4b01cf.png)

#### 5.3 Passkeyの作成

![2023-12-10_10h37_26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49429/1786e7f4-f451-af50-b7fa-9100f4e8a42b.png)

#### 5.4 ログイン

`パスキーを使用して続行する` でログインできれば完了です:tada:

![2023-12-10_10h34_37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49429/cf6b3f3c-3732-7e6c-a668-2cc81f1bda3b.png)


## まとめ

実際のプロダクションのコードの場合だと、もう少しコードを書く必要がありますが、
Passkeyをほぼコードを書くことなく実装できてしまいます。
Auth0便利！

Passkeyの導入を検討してみてはいかがでしょうか