🆔

Hankoを使ってパスキーを使った指紋認証をWebで試してみる

2023/04/19に公開

この記事は?

最近、ヤフーやNTTドコモ、メルカリといった日本で有名な企業がログインにおいて、パスキーを使った認証を採用していること、または、し始めたことを知り、その技術について興味を持ったので調べていました。その中で、パスキーを使った認証が実装できるHankoというライブラリを見つけたので試してみたという記事です。

パスキーとは何か?

筆者はパスキーについて詳しくないため、次の記事がとても参考になりました。
https://blog.agektmr.com/2022/12/passkey.html
https://future-architect.github.io/articles/20221114a/

簡単に言えば、パスキーとは、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月現在はベータ版です。
https://github.com/teamhanko/hanko
また、ドキュメントにはiOS/AndroidのネイティブAPIを用いたモバイルアプリ認証の構築の解説があったり、Hanko CloudというFIDO2の認証サーバーなどがホストされ、ユーザー管理、分析などが可能なIDaaS(Identity as a Service)を提供しています。
参考: https://fidoalliance.org/company/hanko/

実際に試してみる

公式デモサイトを触ってみる

まず、Hankoによる公式のデモサイトがあり、アクセスするだけで手軽に試すことができます。このデモを試すだけでもパスキーを使った認証がどんな感じが体験できるのではないでしょうか。
https://www.passkeys.io/

指紋認証に対応したMacBookProのGoogleChromeでメールアドレスを入力して、ボタンを押していくと次の画面が出るので、指紋認証を行います。
passkeys.ioの認証画面
すると、次のように認証完了し、パスキーとメールアドレスが紐付けされます。
passkeys.ioの認証完了画面

クイックスタートを立ち上げてみる

公式デモサイトでログインの体験はできたので、実際にローカルマシンで試してみたいと思います。
https://github.com/teamhanko/hanko/tree/main/quickstart
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の立ち上げ方から書かれているので、実際に動かして実装を追ってみるのも面白いかもしれません。
https://github.com/teamhanko/hanko/tree/main/backend

Hanko CloudとWebフロントエンドコンポーネントを使ってサイトを公開してみる

さて、ローカルマシンで動かしてみると、やはりWeb上に自分で公開したくなったので、Hanko CloudとWebフロントエンドに統合できるコンポーネントを使って試してみます。Hanko Cloudのコンソールにアクセスして、プロジェクト名とWebフロントエンド用コンポーネントが使用されているWebアプリケーションのURLを入れます。
https://cloud.hanko.io/

URLが必要なのでドキュメントを参考にして、実装したものをVercelなど任意のホスティングサービスで公開します。今回はViteとReactで実装しました。
https://docs.hanko.io/guides/react
実装自体は、hanko-authhanko-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は次の通りです。
https://hanko-sample.vercel.app/

おわりに

今回は、Hankoを使ってパスキーを使った認証をWebで試してみました。Hankoを使うとパスキーを使った認証が割と簡単に実装できそうで、良くできているなという印象を持ちました。
パスキーを使った認証をサービスに組み込むハードルとなるであろう認証サーバーの実装が今後もっと容易になったり、他のIDaaSでサポートされていけば、パスワードレスな世界が近づいていくと感じました。

Voicyテックブログ

Discussion