r-token
r-token is a small token authentication helper for Rust and actix-web.
It provides two token managers:
- In-memory:
RTokenManagerstores tokens in memory with an expiration timestamp. - Redis/Valkey (optional):
RTokenRedisManagerstores tokens in Redis with TTL.
For actix-web, r-token follows a “parameter-as-authentication” style: add RUser to handler parameters, and the request is authenticated automatically via the Actix extractor mechanism.
Features
- Zero boilerplate: no custom middleware required for basic header auth.
- Extractor-first: declaring
RUserprotects the route. - Thread-safe, shared state:
RTokenManagerisCloneand shares an in-memory store. - TTL support:
- In-memory: tokens expire based on a per-login TTL (seconds).
- Redis/Valkey: expiration is enforced by Redis TTL (seconds).
- Redis/Valkey backend (optional):
RTokenRedisManagerstoresuser_idby token key.
Security notes
- This library implements bearer-token authentication. Always use HTTPS in production.
- Token strings grant access. Treat them like passwords: do not log them, do not store them in plaintext client storage without careful threat modeling.
- The Redis backend stores
user_idas the Redis value. If you need stronger protection against Redis data disclosure, consider storing a hashed token (not currently implemented by this crate).
Status
This project is in active development. Review the source code and tests before adopting it in security-sensitive environments.
We have released a stable version, but the API is not yet frozen. We will maintain backward compatibility and will not introduce breaking changes.
Installation
Add r-token to your Cargo.toml:
[]
= "1.0.0"
Feature flags
r-token uses Cargo features to keep dependencies optional:
actix(default): enables theRUserextractor and actix-web integration.redis: enables Redis/Valkey support via therediscrate.redis-actix: convenience feature =redis+actix.rbac: enables role-based access control (RBAC) support.
Examples:
[]
= { = "1.0.0", = false }
[]
= { = "1.0.0", = ["redis-actix"] }
[]
= { = "1.0.0", = ["rbac"] }
[]
= { = "1.0.0", = ["redis-actix", "rbac"] }
Authorization header
The RUser extractor (and the Redis example server) reads the token from Authorization and supports:
Authorization: <token>
Authorization: Bearer <token>
API overview
Core types:
RTokenManager(always available): issues and revokes tokens in memory.RTokenError(always available): error type used by in-memory manager.
Actix integration (requires actix, enabled by default):
RUser:actix_web::FromRequestextractor that validatesAuthorization.
Redis backend (requires redis):
RTokenRedisManager: issues, validates, and revokes tokens backed by Redis/Valkey.
RBAC support (requires rbac):
RTokenManager::login_with_roles(): issues a token with associated roles.RTokenManager::set_roles(): updates roles for an existing token.RTokenManager::get_roles(): retrieves roles for a token.RUser.roles: vector of roles associated with the authenticated user.RUser::has_role(): checks if the user has a specific role.RTokenRedisManager::login_with_roles(): issues a token with roles in Redis.RTokenRedisManager::set_roles(): updates roles for a token in Redis.RTokenRedisManager::get_roles(): retrieves roles for a token in Redis.RTokenRedisManager::validate(): returns bothuser_idandroleswhen RBAC is enabled.
In-memory usage (actix-web)
1. Add endpoints
No manual header parsing is needed. Inject RUser into protected handlers.
use ;
use ;
async
async
async
2. Register and Run
Initialize RTokenManager and register it with your Actix application.
use ;
use RTokenManager;
async
RBAC usage (role-based access control)
When the rbac feature is enabled, you can assign roles to tokens and perform role-based authorization.
In-memory RBAC
use ;
use ;
async
async
async
async
Redis RBAC
use RTokenRedisManager;
async
Behavioral details
In-memory manager:
RTokenManager::login(user_id, ttl_seconds)returns a UUID v4 token string.RTokenManager::renew(token, ttl_seconds)extends an existing token lifetime.RTokenManager::rotate(token, ttl_seconds)issues a new token and revokes the old one.RTokenManager::ttl_seconds(token)returns remaining TTL.- Expiration is tracked by storing an absolute expiration timestamp (milliseconds since Unix epoch).
- Expired tokens are removed when you call
validate()(and will otherwise remain in memory). - You can proactively remove expired tokens via
RTokenManager::prune_expired(). RTokenManager::logout(token)is idempotent: revoking a non-existent token is treated as success.
Actix extractor:
- On success,
RUserprovidesidand the rawtoken. - When RBAC is enabled,
RUseralso providesroles(a vector of role strings). RUser::has_role(role)checks if the user has a specific role.- Failure modes:
401 Unauthorized: missing token, invalid token, or expired token.500 Internal Server Error: token manager missing fromapp_data, or internal mutex poisoned.
Redis manager:
RTokenRedisManager::login(user_id, ttl_seconds)storesprefix + tokenas the key anduser_idas the value, with Redis TTL set tottl_seconds.RTokenRedisManager::renew(token, ttl_seconds)updates the Redis TTL for the token key.RTokenRedisManager::rotate(token, ttl_seconds)issues a new token and deletes the old key.RTokenRedisManager::ttl_seconds(token)returns Redis TTL semantics for the token key.validate(token)returnsOk(None)when the key is absent (revoked or expired).- When RBAC is enabled,
validate(token)returnsOk(Some(user_id))(roles requirevalidate_with_roles(token)). - When RBAC is enabled,
validate_with_roles(token)returnsOk(Some((user_id, roles))). logout(token)deletes the key and is idempotent.
RBAC behavior:
- Tokens can be created with roles via
login_with_roles(). - Roles can be updated on existing tokens via
set_roles(). - Roles can be retrieved via
get_roles(). - When RBAC is enabled,
RUser.rolesis available (empty vector if no roles were assigned). RUser::has_role()performs a case-sensitive string comparison.
Redis/Valkey usage
If you want token persistence and Redis-managed TTL expiration, enable redis (or redis-actix) and use RTokenRedisManager.
You also need a Tokio runtime in your application (do not rely on transitive dependencies):
[]
= { = "1", = ["macros", "rt-multi-thread"] }
use RTokenRedisManager;
async
Usage examples (curl)
Login
# Response: 550e8400-e29b-41d4-a716-446655440000
Access Protected Resource
# Without Token -> 401 Unauthorized
# With Token -> 200 OK
Example servers in this repo
In-memory (actix-web)
Redis/Valkey (actix-web)
Environment variables:
REDIS_URL(default:redis://127.0.0.1/)R_TOKEN_PREFIX(default:r_token:token:)
REDIS_URL=redis://127.0.0.1/
Roadmap
- In-memory token management + extractor
- Token expiration (TTL)
- Redis/Valkey backend token storage (optional)
- Role-based access control (RBAC)
- Cookie support
- In-memory token validation API (non-actix)
- Redis actix-web extractor (parameter-as-authentication)
- Configurable token sources (header/cookie name, priority)
License
MIT