rustauth-actix-web 0.3.0

Actix Web integration for RustAuth.
Documentation

rustauth-actix-web

Actix Web adapter for RustAuth.

What It Is

rustauth-actix-web mounts the framework-neutral RustAuth handler into an Actix Web application. Use it when your server is built with Actix Web and you want RustAuth routes under a path such as /api/auth.

What It Provides

  • RustAuthActixWebExtmount_routes and mount_at_base_path for mounting on both RustAuth and Arc<RustAuth>. Both take RustAuthActixWebOptions explicitly (use RustAuthActixWebOptions::default() for defaults).
  • handle — escape hatch for single-request integration without building a scope; takes RustAuthActixWebOptions as the second argument.
  • RustAuthActixWebOptions — request body limits, peer socket IP propagation, and optional base URL inference behind explicit proxy trust.

Quick Start

use std::sync::Arc;

use actix_web::{App, HttpServer};
use rustauth::prelude::*;
use rustauth_actix_web::{RustAuthActixWebExt, RustAuthActixWebOptions};

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    let auth = Arc::new(
        RustAuth::builder()
            .secret("secret-a-at-least-32-chars-long!!")
            .base_url("https://app.example.com/api/auth")
            .build()
            .await
            .expect("valid RustAuth config"),
    );

    HttpServer::new(move || {
        App::new().service(
            auth.mount_at_base_path(RustAuthActixWebOptions::default())
                .expect("valid RustAuth Actix mount"),
        )
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

When Actix Web is exposed directly to clients, ensure the server records peer socket addresses so RustAuth can use the real client IP for rate limiting. The adapter reads HttpRequest::peer_addr() when use_peer_addr_for_ip is enabled (the default).

Choosing a mount API

Goal API Notes
Standalone auth server auth.mount_at_base_path(RustAuthActixWebOptions::default()) Nests at base_path
Shared Arc<RustAuth> in app state auth.mount_routes(RustAuthActixWebOptions::default()) + your .service() nest You control prefix
Let rustauth-actix-web nest auth.mount_at_base_path(RustAuthActixWebOptions::default()) Do not nest again
Custom state on auth routes mount_routes(options) Same as above

When you nest manually with mount_routes(), ensure your outer scope uses the same path as RustAuthOptions::base_path and that base_url matches. The fallible mount helpers validate this; you can also call validate_mount_config explicitly before nesting.

Notes

  • Default mount path comes from RustAuthOptions::base_path, falling back to /api/auth.
  • base_path("/") and base_path("") mount RustAuth routes at the application root.
  • Default request body limit is 10 MiB; oversized bodies return JSON 413 PAYLOAD_TOO_LARGE.
  • Configure RustAuthOptions::base_url for production deployments. If you intentionally need request-derived public URLs, enable RustAuthActixWebOptions::infer_base_url_from_request(true) and configure trusted origins explicitly.
  • Public x-forwarded-host and x-forwarded-proto headers are ignored unless both base URL inference and RustAuthActixWebOptions::trust_proxy_headers_for_base_url(true) are enabled.
  • Do not trust public x-forwarded-for headers unless traffic is terminated by a trusted reverse proxy.
  • Do not run body-consuming Actix middleware on auth routes before rustauth-actix-web (same idea as avoiding express.json() before Better Auth on Express).
  • actix-web is pinned with default-features = false in the workspace; only the features required by this adapter are enabled.

Actix adapter limitations

Compared to rustauth-axum, this adapter intentionally does not preserve:

  • Response HTTP version — Actix HttpResponse has no safe response-version setter; status, headers, and body are preserved (src/response.rs).
  • Opaque response extensionshttp::Extensions is not iterable; custom ApiResponse extension types are not round-tripped through Actix.
  • Arbitrary request extensions — only RustAuth-known types are copied from HttpRequest into ApiRequest: RequestClientIp, RequestBaseUrl, and OAuthBaseUrlOverride (src/request.rs). Plugin or middleware extensions outside that set are not forwarded unless you set one of those types explicitly.

Contract tests cover the preserved behavior; omitted Axum cases are documented in UPSTREAM.md.

Status

Experimental beta. Scope composition, request extraction, and adapter options may change before stable release.

Better Auth compatibility

Server-side Actix Web HTTP adapter for mounting RustAuth routes. Aligned with Better Auth 1.6.9 where it matters for this crate; RustAuth is not a line-by-line port.

For route-level parity, test counts, intentional differences, and known gaps, see UPSTREAM.md.

Links