Axum

AxumでのミドルウェアとJWT認証実装ガイド

ⓘ本ページはプロモーションが含まれています

もっとスキルを活かしたいエンジニアへ

スポンサードリンク
働き方から選べる

無料で使えて良質な案件の情報収集ができるサービス

エンジニアの世界では、「いつでも動ける状態を作っておけ」とよく言われます。
技術やポートフォリオがあっても、自分に合う案件情報を日常的に見れていないと、いざ動こうと思った時に比較や判断が難しくなってしまいます。
普段から案件情報が集まる環境を作っておくと、良い案件が出た時にすぐ動きやすくなりますよ。
筆者自身も、メガベンチャー勤務時代に年収1,500万円を超えた経験があります。振り返ると、技術だけでなく「どんな案件や働き方があるか」を日頃から見ていたことが、キャリアの選択肢を広げるきっかけになりました。
このブログを読んでくれた方に感謝を込めて、実際に使っている情報収集サービスを紹介します。

フルリモート・週3日・高単価、どんな条件も妥協したくないなら

フリーランスボードに無料会員登録する

利用者10万人以上。業界最大規模45万件の案件。AIマッチ機能や無料の相場情報が人気。

年収800万円以上のキャリアアップ・ハイクラス正社員を視野に入れているなら

Beyond Careerに無料相談する

内定獲得率90%以上。紹介先企業とは役員クラスのコネクションがある安心と信頼できるエージェント。


スポンサードリンク

Axum の基本構造とミドルウェア概念

Axum アプリは「Router → Service → Layer」という三層構造で動作します。この流れを理解すると、リクエストの前後に処理を差し込むミドルウェアがシンプルに実装でき、認証・ロギング・トレーシングといった横断的な機能を全ルートへ一括適用できます。

Router と Service の役割

  • Router: エンドポイントとハンドラ(Service)を紐付ける。
  • Service: 実際にリクエストを処理する関数や構造体。
  • Layer: Service をラップし、リクエスト/レスポンスに対して前処理・後処理を行う。

ミドルウェア実装例(ロギング)

以下は Layer として実装したシンプルなロガーです。middleware::from_fn で関数ベースのミドルウェアを作り、.layer() に渡すだけで全ルートに適用できます。

ポイントLayerService を包むだけなので、認証・トレーシング等の横断処理も同様に実装できます。


JWT の概要と jsonwebtoken クレートの導入

JSON Web Token(JWT)は ヘッダー・ペイロード・署名 の三部構成で、認可情報を安全かつ自己完結的に運搬できる標準規格です。本節では Rust で広く利用されている jsonwebtoken クレートの基本的な使い方と、実装時に注意すべき設定項目を紹介します。

Cargo.toml の正しい記述

テスト以外で署名検証を無効化するオプションは絶対に使用しないようにしてください。代わりにデフォルトの機能だけを有効にします。

  • 本番環境では --no-default-features または --features "" でビルドし、危険オプションを除外します。
  • テストコードだけ #[cfg(feature = "test-insecure")] として有効化すれば、安全性を損なうことなくテストが可能です。

トークン生成・検証の最小実装例

重要secret は環境変数やシークレット管理サービスから取得し、コードにハードコーディングしないこと。


鍵管理・アルゴリズム選択・ローテーション手順

対称鍵(HS256)と非対称鍵(RS256)は 運用コスト・安全性・パフォーマンス がそれぞれ異なります。この節では実際のプロダクトでどちらを採用すべきか判断する指標と、キーの安全な保管・ローテーション手順を具体的に示します。

HS256 と RS256 の比較(正しいパフォーマンス情報)

項目 HS256 (対称) RS256 (非対称)
鍵の構成 1 本のシークレット 秘密鍵 + 公開鍵のペア
計算コスト 高速(HMAC は CPU に優しい) 低速(RSA の署名・検証は比較的重い)
鍵配布方式 全サービスが同一シークレットを保持 公開鍵だけを共有すれば OK、秘密鍵は安全に保管
ローテーション キー変更時に全サービスで更新が必要 秘密鍵のみローテーションし、公開鍵は再配布不要
主な利用シーン 内部マイクロサービス間・短期トークン 外部クライアントやサードパーティ連携

アルゴリズム選択の指針

  1. 内部限定か外部公開か
  2. 同一組織内だけで完結するマイクロサービス間通信 → HS256(シンプル&高速)
  3. 外部クライアントやサードパーティへトークンを配布 → RS256(鍵管理が容易)

  4. トークンの有効期間

  5. 短時間(15〜60 分)のアクセストークンは HS256 でも十分安全。
  6. 長期的に保持するリフレッシュトークンや重要権限付与は RS256 が推奨。

  7. インフラ要件

  8. ハードウェアリソースが限られる環境(IoT デバイス等) → HS256
  9. 高いセキュリティ基準が求められる金融系・医療系 → RS256 もしくは ES256

鍵の安全な保管方法

環境 推奨手段
ローカル開発 .env ファイル+ dotenvy.gitignore に必ず追加)
Docker コンテナ Docker Secret (docker run -e JWT_SECRET=$(cat /run/secrets/jwt_secret))
Kubernetes Secret リソースを envFrom または volume マウントで注入
CI/CD (GitHub Actions 等) ワークフローの Secrets 機能から環境変数として提供
サーバーレス (AWS Lambda) AWS Secrets Manager / Parameter Store から取得

鍵ローテーションの具体的手順(例:RS256)

  1. 新鍵ペア生成
    bash
    openssl genpkey -algorithm RSA -out private_new.pem -pkeyopt rsa_keygen_bits:2048
    openssl rsa -pubout -in private_new.pem -out public_new.pem
  2. シークレット管理サービスに登録(例:AWS Secrets Manager)
  3. private_currentprivate_old に名前変更
  4. private_new を新しいシークレットとして保存

  5. アプリケーション側の切り替えロジック
    rust
    // 環境変数でキー名を取得
    let key_name = env::var("JWT_PRIVATE_KEY_NAME").unwrap_or_else(|_| "private_current".into());
    let private_key_pem = secret_manager.get(&key_name).await?;

  6. 段階的デプロイ
  7. 新しい公開鍵 (public_new.pem) をすべてのサービスに配布。
  8. 旧鍵で署名されたトークンは 一定期間(例:7 日) 有効に保ち、徐々に新鍵へ移行。

  9. 古鍵の廃止

  10. 移行完了後、private_oldpublic_old を安全に削除。
  11. ログで「旧鍵使用トークンが残っていない」ことを確認。

認証ミドルウェアと保護ルートの実装

Axum では ExtractorFromRequest 実装)を用いることで、リクエストごとに JWT 検証ロジックを自動的に走らせられます。この節では AuthUser 抽出子の作り方と、保護されたハンドラへの適用例を示します。

Extractor (FromRequest) の実装手順

  1. 認証情報構造体 を定義
  2. エラー型 として IntoResponse を実装し、401 を返す
  3. async_traitFromRequest を実装し、ヘッダー取得・トークン検証・クレーム抽出を行う

保護されたハンドラの例

AuthUser が取得できなかった場合は自動的に AuthError が返り、ステータスコード 401 と共に「認証に失敗しました」というメッセージがクライアントへ送信されます。

エラーハンドリングとリフレッシュトークンの概念

ケース 処理内容
署名不正 decode がエラー → AuthError (401)
有効期限切れ Validation::leeway を設定しつつ、期限超過は同様に 401
リフレッシュトークン使用 /refresh エンドポイントで長期 RSA 署名トークンを受け取り、検証後に新しい短期 HS256 アクセストークンを発行

実装のヒント

  • リフレッシュトークンは DB にハッシュ保存し、盗難時にローテーションできるようにする。
  • トークン失効情報(ブラックリスト)は Redis 等の高速キャッシュで管理するとスケールしやすい。

テスト・デプロイ・ベストプラクティス

実装した認証ロジックは ユニットテスト統合テスト の両方で検証し、CI に組み込むことで品質を保証します。また、本番環境へ安全にデプロイするためのシークレット管理手順も合わせて示します。

ユニットテストと統合テストの書き方

  • ユニットテストcreate_hs256verify_hs256 のロジックだけを対象にし、期限切れや不正署名のシナリオも網羅する。
  • 統合テストはミドルウェア全体が期待通りに動くか(例:ログイン後のトークンで保護ルートへアクセスできる)を確認。

CI/CD におけるシークレット注入表

環境 注入方法
GitHub Actions secrets.JWT_SECRETenv: で渡す
GitLab CI $CI_JOB_TOKEN 経由で Vault から取得し、環境変数に展開
Azure Pipelines キーボルトのシークレットを variables にマッピング
CircleCI context に登録したシークレットを自動注入

ベストプラクティスまとめ

  1. コードベースに鍵情報は絶対に残さない.gitignore.env* を必ず追加)。
  2. ローテーション手順をドキュメント化し、定期的に実行。古い鍵は一定期間だけ有効にしてバックワード互換性を保つ。
  3. アルゴリズムは RS256 か ES256(楕円曲線)を本番で推奨。HS256 は内部限定の短期トークンに留める。
  4. エラーメッセージは情報漏洩防止のため簡潔にし、スタックトレース等はログにのみ出力。

まとめ

  • Axum の LayerService を組み合わせれば、認証・ロギング・トレーシングを統一的に実装できる。
  • jsonwebtoken は安全なデフォルト設定で利用し、テスト以外での署名無効化オプションは削除すること。
  • アルゴリズム選択は パフォーマンスと運用コスト を基準に判断し、鍵ローテーション手順を明文化しておく。
  • Extractor による認証ミドルウェアで保護ルートを簡潔に実装し、エラーハンドリングとリフレッシュトークンの流れも併せて設計する。
  • ユニット/統合テスト・CI への組み込み、シークレット管理まで網羅すれば、本番環境でも安心してデプロイできる JWT 認証基盤が完成します。

ぜひこの手順をローカルで試した後、ステージング環境へ展開し、実運用に向けた最終調整を行ってください。安全かつ高速な認証システムが、あなたの Rust アプリケーションの価値を大きく高めてくれるはずです。

スポンサードリンク

もっとスキルを活かしたいエンジニアへ

スポンサードリンク
働き方から選べる

無料で使えて良質な案件の情報収集ができるサービス

エンジニアの世界では、「いつでも動ける状態を作っておけ」とよく言われます。
技術やポートフォリオがあっても、自分に合う案件情報を日常的に見れていないと、いざ動こうと思った時に比較や判断が難しくなってしまいます。
普段から案件情報が集まる環境を作っておくと、良い案件が出た時にすぐ動きやすくなりますよ。
筆者自身も、メガベンチャー勤務時代に年収1,500万円を超えた経験があります。振り返ると、技術だけでなく「どんな案件や働き方があるか」を日頃から見ていたことが、キャリアの選択肢を広げるきっかけになりました。
このブログを読んでくれた方に感謝を込めて、実際に使っている情報収集サービスを紹介します。

フルリモート・週3日・高単価、どんな条件も妥協したくないなら

フリーランスボードに無料会員登録する

利用者10万人以上。業界最大規模45万件の案件。AIマッチ機能や無料の相場情報が人気。

年収800万円以上のキャリアアップ・ハイクラス正社員を視野に入れているなら

Beyond Careerに無料相談する

内定獲得率90%以上。紹介先企業とは役員クラスのコネクションがある安心と信頼できるエージェント。


-Axum