r-token
README: 日本語(このページ) | English
r-token は Rust と actix-web 向けの小さな token 認証ヘルパーです。
token マネージャは 2 種類あります:
- インメモリ:
RTokenManagerが token をメモリ上に保持し、期限は絶対時刻(ミリ秒)で管理します。 - Redis/Valkey(任意):
RTokenRedisManagerが token を Redis に保存し、期限は Redis の TTL(秒)に任せます。
actix-web では “parameter-as-authentication” スタイルを採用しています。handler の引数に RUser を追加するだけで、Actix の extractor が Authorization(または cookie)を自動検証し、リクエストを認証済みにします。
特長
- ボイラープレート最小: 基本的な header 認証に独自ミドルウェア不要。
- Extractor-first:
RUserを引数に書くだけでルートを保護。 - スレッドセーフな共有状態:
RTokenManagerはCloneでき、同じインメモリストアを共有。 - TTL 対応:
- インメモリ: login 時の TTL(秒)から期限を計算。
- Redis/Valkey: Redis の TTL(秒)が期限を強制。
- Redis/Valkey バックエンド(任意):
RTokenRedisManagerがprefix + tokenを key として保存。
セキュリティ注意
- 本ライブラリは bearer-token 認証です。本番では必ず HTTPS を使ってください。
- token 文字列はアクセス権そのものです。パスワード同様に扱い、ログに出さない/脅威モデル無しでクライアント側に平文保存しないでください。
- Redis バックエンドは value として
user_id(または RBAC 時は JSON)を保存します。Redis のデータ漏えいが懸念される場合は、token を hash 化して key として保存する方式を検討してください(現状この crate では未実装)。
ステータス
本プロジェクトは活発に開発中です。セキュリティ要件が厳しい環境では、導入前にソースとテストを確認してください。
安定版はリリースしていますが、API はまだ完全固定ではありません。後方互換性を維持し、破壊的変更は導入しない方針です。
インストール
Cargo.toml に追加します:
[]
= "1.0.2"
Cargo features
r-token は Cargo features で依存を任意化しています:
actix(デフォルト):RUserextractor と actix-web 連携を有効化します。redis:rediscrate を使った Redis/Valkey バックエンドを有効化します。redis-actix: 便利 feature(redis+actix)。rbac: ロールベースアクセス制御(RBAC)を有効化します。
例:
[]
= { = "1.0.2", = false }
[]
= { = "1.0.2", = ["redis-actix"] }
[]
= { = "1.0.2", = ["rbac"] }
[]
= { = "1.0.2", = ["redis-actix", "rbac"] }
Authorization header
RUser extractor(および Redis サンプルサーバー)は Authorization から token を読み取り、次の形式に対応します:
Authorization: <token>
Authorization: Bearer <token>
API 概要
コア型:
RTokenManager(常に利用可): インメモリで token を発行・失効します。RTokenError(常に利用可): インメモリマネージャが使うエラー型です。
Actix 連携(actix が必要、デフォルトで有効):
RUser:Authorization(または cookie)を検証するactix_web::FromRequestextractor。
Redis バックエンド(redis が必要):
RTokenRedisManager: Redis/Valkey をバックエンドに token を発行・検証・失効します。
RBAC(rbac が必要):
RTokenManager::login_with_roles(): roles を紐づけた token を発行します。RTokenManager::set_roles(): 既存 token の roles を更新します。RTokenManager::get_roles(): token の roles を取得します。RUser.roles: 認証済みユーザーに紐づく roles(Vec<String>)。RUser::has_role(): 指定 role を持つか判定します。RTokenRedisManager::login_with_roles(): Redis に roles 付き token を発行します。RTokenRedisManager::set_roles(): Redis 上の token の roles を更新します。RTokenRedisManager::get_roles(): Redis 上の token の roles を取得します。RTokenRedisManager::validate(): RBAC 有効時はuser_idとrolesを返します。
インメモリ利用例(actix-web)
1. エンドポイントを追加
手動で header を解析する必要はありません。保護したい handler に RUser を引数として追加します。
use ;
use ;
async
async
async
2. 登録して起動
RTokenManager を初期化し、Actix の app state に登録します。
use ;
use RTokenManager;
async
RBAC 利用例(role-based access control)
rbac feature を有効にすると、token に roles を紐づけてロールベースの認可を行えます。
インメモリ RBAC
use ;
use ;
async
async
async
async
Redis RBAC
use RTokenRedisManager;
async
振る舞いの詳細
インメモリマネージャ:
RTokenManager::login(user_id, ttl_seconds)は UUID v4 の token 文字列を返します。RTokenManager::renew(token, ttl_seconds)は既存 token の期限を延長します。RTokenManager::rotate(token, ttl_seconds)は新 token を発行し、旧 token を失効させます。RTokenManager::ttl_seconds(token)は残り TTL(秒)を返します。- 期限は「Unix epoch ミリ秒の絶対時刻」として保存して追跡します。
- 期限切れ token は
validate()呼び出し時に削除されます(それ以外のタイミングでは残り続けます)。 RTokenManager::prune_expired()で期限切れ token を能動的に掃除できます。RTokenManager::logout(token)は冪等です。存在しない token を失効しても成功扱いです。
Actix extractor:
- 成功時、
RUserはidと生のtokenを提供します。 - RBAC 有効時は
RUser.rolesも提供されます(role 文字列のVec<String>)。 RUser::has_role(role)は指定 role を持つか判定します。- 失敗時:
401 Unauthorized: token が無い/不正/期限切れ。500 Internal Server Error:app_dataにマネージャが無い/内部 mutex が poisoned。
Redis マネージャ:
RTokenRedisManager::login(user_id, ttl_seconds)はprefix + tokenを key、user_idを value として保存し、TTL をttl_seconds(秒)に設定します。RTokenRedisManager::renew(token, ttl_seconds)は token key の Redis TTL を更新します。RTokenRedisManager::rotate(token, ttl_seconds)は新 token を発行し、旧 key を削除します。RTokenRedisManager::ttl_seconds(token)は token key の Redis TTL(Redis の意味論)を返します。validate(token)は key が無い(失効済み/期限切れ)ときOk(None)を返します。- RBAC 有効時、
validate(token)はOk(Some(user_id))を返します(roles が必要ならvalidate_with_roles(token))。 - RBAC 有効時、
validate_with_roles(token)はOk(Some((user_id, roles)))を返します。 logout(token)は key を削除し、冪等です。
RBAC の挙動:
login_with_roles()で roles 付き token を作れます。set_roles()で既存 token の roles を更新できます。get_roles()で roles を取得できます。- RBAC 有効時は
RUser.rolesが利用できます(roles 未設定なら空ベクタ)。 RUser::has_role()は大文字小文字を区別して比較します。
Redis/Valkey 利用例
token を永続化し、期限切れを Redis の TTL で管理したい場合は redis(または redis-actix)を有効にし、RTokenRedisManager を使います。
アプリ側で Tokio runtime も必要です(推移的依存に頼らないでください):
[]
= { = "1", = ["macros", "rt-multi-thread"] }
use RTokenRedisManager;
async
利用例(curl)
Login
# レスポンス例: 550e8400-e29b-41d4-a716-446655440000
保護されたリソースにアクセス
# token 無し -> 401 Unauthorized
# token あり -> 200 OK
このリポジトリのサンプルサーバー
インメモリ(actix-web)
Redis/Valkey(actix-web)
環境変数:
REDIS_URL(デフォルト:redis://127.0.0.1/)R_TOKEN_PREFIX(デフォルト:r_token:token:)
REDIS_URL=redis://127.0.0.1/
ロードマップ
- インメモリ token 管理 + extractor
- token 期限(TTL)
- Redis/Valkey バックエンド(任意)
- ロールベースアクセス制御(RBAC)
- Cookie 対応
- インメモリ token 検証 API(non-actix)
- Redis actix-web extractor(parameter-as-authentication)
- token 取得元の設定(header/cookie 名、優先順位)
ライセンス
MIT