Hankoを使ってパスキーを使った指紋認証をWebで試してみる
この記事は?
最近、ヤフーやNTTドコモ、メルカリといった日本で有名な企業がログインにおいて、パスキーを使った認証を採用していること、または、し始めたことを知り、その技術について興味を持ったので調べていました。その中で、パスキーを使った認証が実装できるHankoというライブラリを見つけたので試してみたという記事です。
パスキーとは何か?
筆者はパスキーについて詳しくないため、次の記事がとても参考になりました。
簡単に言えば、パスキーとは、FIDO(ファイド, Fast IDentity Online)という認証技術で使われる資格情報の一つであり、Web Authenticationの仕様(Web技術標準化団体W3Cが策定)とClient-to-Authenticator Protocol(CTAP)の仕様(FIDOの標準化団体FIDO Allianceが策定)で構成されるFIDO2の仕様で実現されているようです。
参考: https://fidoalliance.org/fido2/
具体的には、この仕様に準じた実装により、指紋認証などの生体認証をキーとしてWebサービスやモバイルアプリでユーザーの識別ができ、それを使ってアカウントへのログインなどが可能になります。
認証の仕組みや技術に関しては、上記参考記事などで解説されているので省略し、ここからは、そのパスキーを使った認証が実装できるHankoというライブラリに触れていきたいと思います。
Hankoとは
Hankoは、パスキーを使った認証が実装できるオープンソースのユーザー認証システムであり、主にFIDO2サーバーやWebフロントエンドに統合できるコンポーネントがGithub上で公開、開発されています。
READMEによると、2023年4月現在はベータ版です。
また、ドキュメントにはiOS/AndroidのネイティブAPIを用いたモバイルアプリ認証の構築の解説があったり、Hanko CloudというFIDO2の認証サーバーなどがホストされ、ユーザー管理、分析などが可能なIDaaS(Identity as a Service)を提供しています。
参考: https://fidoalliance.org/company/hanko/
実際に試してみる
公式デモサイトを触ってみる
まず、Hankoによる公式のデモサイトがあり、アクセスするだけで手軽に試すことができます。このデモを試すだけでもパスキーを使った認証がどんな感じが体験できるのではないでしょうか。
指紋認証に対応したMacBookProのGoogleChromeでメールアドレスを入力して、ボタンを押していくと次の画面が出るので、指紋認証を行います。
すると、次のように認証完了し、パスキーとメールアドレスが紐付けされます。
クイックスタートを立ち上げてみる
公式デモサイトでログインの体験はできたので、実際にローカルマシンで試してみたいと思います。
QuickStart用のREADMEが用意されているので、書いてある通り、git cloneしてから、docker環境が用意されている前提で、dockerのコマンドを実行します。$ git clone https://github.com/teamhanko/hanko.git
$ docker compose -f deploy/docker-compose/quickstart.yaml -p "hanko-quickstart" up --build
これで、ローカルマシンでHankoのFIDO2認証用サーバー、Webフロントエンドサーバー、メールアドレス確認用のSMTPサーバーmailslurperなどが起動します。
localhost:8888でWebフロントエンドサーバーが開かれているため、アクセスすると、ログインページを開くことができ、あとは公式デモサイトと同じようにログインできます。
GitHubリポジトリのbackend, frondendのフォルダにもREADMEが書かれており、backendについてはDBの立ち上げ方から書かれているので、実際に動かして実装を追ってみるのも面白いかもしれません。
Hanko CloudとWebフロントエンドコンポーネントを使ってサイトを公開してみる
さて、ローカルマシンで動かしてみると、やはりWeb上に自分で公開したくなったので、Hanko CloudとWebフロントエンドに統合できるコンポーネントを使って試してみます。Hanko Cloudのコンソールにアクセスして、プロジェクト名とWebフロントエンド用コンポーネントが使用されているWebアプリケーションのURLを入れます。
URLが必要なのでドキュメントを参考にして、実装したものをVercelなど任意のホスティングサービスで公開します。今回はViteとReactで実装しました。 実装自体は、hanko-authとhanko-profileというコンポーネントを使っただけです。
- HankoAuth.tsx
import { useEffect, useCallback } from "react";
import { useNavigate } from "react-router-dom";
import { register } from "@teamhanko/hanko-elements";
export default function HankoAuth({ hankoApi }: { hankoApi: string }) {
const navigate = useNavigate();
const redirectAfterLogin = useCallback(() => {
// successfully logged in, redirect to a page in your application
navigate("/profile", { replace: true });
}, [navigate]);
useEffect(() => {
document.addEventListener("hankoAuthSuccess", redirectAfterLogin);
return () =>
document.removeEventListener("hankoAuthSuccess", redirectAfterLogin);
}, [redirectAfterLogin]);
useEffect(() => {
// register the component
// see: https://github.com/teamhanko/hanko/blob/main/frontend/elements/README.md#script
register({ shadow: true })
.then(()=>{
})
.catch((error) => {
// handle error
});
}, []);
return (
<hanko-auth api={hankoApi} />
);
}
- HankoProfile.tsx
import { useEffect } from "react";
import { register } from "@teamhanko/hanko-elements";
import { useNavigate } from "react-router-dom";
export default function HankoProfile({ hankoApi }: { hankoApi: string }) {
const navigate = useNavigate();
useEffect(() => {
// register the component
// see: https://github.com/teamhanko/hanko/blob/main/frontend/elements/README.md#script
register({ shadow: true })
.catch((error) => {
// handle error
navigate('/')
});
}, []);
return (
<hanko-profile api={hankoApi} />
);
};
その後、Hanko CloudにサービスのURLを入力して進み、少し経つと認証用サーバーのURLが入手できるので、それをフロントエンド側で環境変数として設定して、HankoのコンポーネントにPropsとして渡すと、デモサイトと同じ挙動が実現できます。
今回試しに作成したURLは次の通りです。
おわりに
今回は、Hankoを使ってパスキーを使った認証をWebで試してみました。Hankoを使うとパスキーを使った認証が割と簡単に実装できそうで、良くできているなという印象を持ちました。
パスキーを使った認証をサービスに組み込むハードルとなるであろう認証サーバーの実装が今後もっと容易になったり、他のIDaaSでサポートされていけば、パスワードレスな世界が近づいていくと感じました。
Discussion