1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

パスワードなしの認証を試す: oauth2-passkey ライブデモ

1
Posted at

この記事は ktaka.blog.ccmp.jp の記事 のクロスポストです。

oauth2-passkey は、OAuth2 と Passkey を組み合わせたパスワードレス認証を、少ないコードで Rust の Web アプリに組み込めるライブラリです。

デモサイト passkey-demo.ccmp.jp を用意しました。
実際の操作を2本の動画で紹介し、その後にコードの使い方を説明します。


デモ 1: Google で登録して Passkey を追加

デモ1: Google登録とPasskey追加

まず新規ユーザーとしてログインする流れです。

  1. ログインページには「Register / Sign in with Google」と「Sign in with Passkey」の2つのボタンがあります。
  2. 「Register / Sign in with Google」を押すと、おなじみの Google アカウント選択画面が開きます。
  3. Google 認証が終わると、すぐに 「Passkey を作成しますか?」 というダイアログが出ます。これがこのライブラリの特徴の一つである 「Passkey プロモーション」 です。OAuth2 でログインしたユーザーに Passkey の登録を自然に促します。
  4. Passkey を作成するとダッシュボードに遷移し、My Account や Admin Panel にアクセスできます。
  5. My Account ページでは、ユーザー情報・Passkey 資格情報・連携 OAuth2 アカウント・ログイン履歴を一覧で確認できます。

いつもの Google ログインで始めて、そのまま Passkey も登録できるのがこの仕組みのよいところです。

デモ 2: Passkey でサインイン

デモ2: Passkeyでサインイン

続いて、同じユーザーが Passkey だけでログインする流れです。

  1. ログインページで「Sign in with Passkey」を押すと、ブラウザの Passkey ダイアログが表示されます。
  2. 指紋や顔認証で本人確認をすれば、それだけでログインが完了します。Google へのリダイレクトもパスワード入力も要りません。
  3. ログイン履歴には Passkey と OAuth2 の両方のエントリーが残るので、いつ・どの方法でログインしたか確認できます。

Passkey を一度登録してしまえば、普段のログインはこれだけです。高速で、フィッシングにも強い認証が手に入ります。

試してみる

デモサイトはこちらです: passkey-demo.ccmp.jp

  • Google でサインイン → Passkey を登録 → Passkey でサインイン、という一連の流れを試せます
  • デモでは全ユーザーに管理者権限が付与されるので、管理パネルも自由に操作できます
  • ログイン履歴ではデバイスや認証方法の詳細も確認できます

データはメモリ上に保存されていて、サーバー再起動時にリセットされます。気軽にどうぞ。

oauth2-passkey とは

oauth2-passkey は、Web アプリにパスワードレス認証を追加するための Rust ライブラリです。2種類の認証方式を一つのライブラリで扱えます。

  • OAuth2 (Google) -- ユーザーにとって馴染みのある、ワンクリックの登録・ログイン
  • Passkeys (WebAuthn/FIDO2) -- 指紋・顔・セキュリティキーによる、フィッシング耐性のあるログイン

想定する運用フローは、まず Google で登録してもらい、その流れで Passkey も追加してもらう形です。デバイスを紛失した場合でも Google 経由でログインできるので、Passkey 一本に依存するリスクを回避できます。

クイックスタート

Axum アプリへの組み込みは以下のようになります。

use axum::{Router, routing::get, response::IntoResponse};
use oauth2_passkey_axum::{AuthUser, oauth2_passkey_full_router};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    oauth2_passkey_axum::init().await?;

    let app = Router::new()
        .route("/", get(home))
        .route("/protected", get(protected))
        .merge(oauth2_passkey_full_router());

    let listener = tokio::net::TcpListener::bind("0.0.0.0:3001").await?;
    axum::serve(listener, app).await?;
    Ok(())
}

async fn home() -> &'static str {
    "Welcome! Visit /o2p/user/login to sign in"
}

async fn protected(user: AuthUser) -> impl IntoResponse {
    format!("Hello, {}!", user.account)
}

oauth2_passkey_full_router() を呼ぶと、/o2p/* 以下に、ログインページ・OAuth2 フロー・Passkey の登録/認証・ユーザーアカウント管理・管理パネルなど、一式のルートが追加されます。

あとは環境変数で Google OAuth2 のクレデンシャルとセッションシークレットを設定すれば動きます。詳しくは Getting Started ガイドをご覧ください。

機能一覧

機能 説明
デュアル認証 OAuth2 (Google) と Passkeys を一つのライブラリで提供
組み込み UI ログインページ、ユーザーアカウント画面、管理パネル付き
Passkey プロモーション OAuth2 ユーザーに Passkey 登録を自然に提案
ログイン履歴 IP・User-Agent・認証器の詳細を自動記録
セッション管理 セキュアな Cookie、セッション競合ポリシー、強制ログアウト
管理パネル ユーザー管理、監査ログ、管理者の誤操作防止
テーマ 9種の CSS テーマを同梱、カスタムテーマにも対応
ストレージ SQLite(開発用)/PostgreSQL(本番用)、キャッシュは Redis またはインメモリに対応

リンク

背景

このライブラリは、2025年初頭に Passkey 認証をスクラッチで実装した記事がきっかけで生まれました。そのとき WebAuthn プロトコルを一から学んだ経験をもとに、OAuth2 連携・セッション管理・UI を備えた汎用ライブラリとして仕立て直しました。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?