Authkestra

Actix-web

Use authkestra-actix to integrate authentication into your Actix-web applications.

authkestra-actix provides a seamless integration with Actix Web, offering type-safe extractors and helper functions to manage authentication flows with minimal boilerplate.

Extractors

Authkestra provides two primary extractors to identify users in your request handlers:

AuthSession

Used for session-based authentication (standard web apps). It attempts to find a session ID in the request cookies and retrieves the associated user identity from the session store.

use authkestra_actix::AuthSession;
use actix_web::{get, HttpResponse, Responder};

#[get("/profile")]
async fn profile(AuthSession(session): AuthSession) -> impl Responder {
    let identity = &session.identity;
    
    HttpResponse::Ok().json(serde_json::json!({
        "username": identity.username,
        "email": identity.email,
        "provider": identity.provider_id
    }))
}

AuthToken

Used for JWT-based authentication (SPAs or Mobile apps). It validates a JWT provided in the Authorization: Bearer <token> header.

use authkestra_actix::AuthToken;

#[get("/api/protected")]
async fn protected_resource(AuthToken(claims): AuthToken) -> impl Responder {
    let identity = claims.identity.unwrap();
    HttpResponse::Ok().body(format!("Hello, {}!", identity.username.unwrap_or_default()))
}

Route Registration

The actix_scope() helper method automatically registers the necessary OAuth routes (/auth/{provider} and /auth/{provider}/callback) for all providers configured in your Authkestra instance.

use authkestra_actix::AuthkestraActixExt;
use authkestra_flow::Authkestra;

// ... configure authkestra ...

App::new()
    .app_data(web::Data::new(authkestra.clone()))
    .service(authkestra.actix_scope()) // Registers /auth/... routes

Configuration with Typestates

Authkestra uses a typestate pattern to ensure that your application is correctly configured at compile time.

Session-based Application

For a traditional web app using sessions:

use authkestra_flow::Authkestra;
use authkestra_session::MemoryStore;
use std::sync::Arc;

let session_store = Arc::new(MemoryStore::default());

let authkestra = Authkestra::builder()
    .session_store(session_store)
    .session_config(SessionConfig::default())
    .build();

Token-based Application (Stateless)

For an API that issues or validates JWTs:

use authkestra_flow::Authkestra;
use std::sync::Arc;

let authkestra = Authkestra::builder()
    .jwt_secret(b"your-32-byte-long-secret-key-here!!")
    .jwt_issuer("my-app")
    .build();

SPA Example: JWT Authentication

In a Single Page Application (SPA), you typically want the backend to exchange the OAuth code for a JWT that the frontend can store and use for subsequent requests.

1. Configure Authkestra

To issue JWTs, you must provide a TokenManager (or use the jwt_secret helper) to the Authkestra builder.

let authkestra = Authkestra::builder()
    .provider(OAuth2Flow::new(GithubProvider::new(client_id, client_secret, redirect_uri)))
    .jwt_secret(b"a-very-secret-key-that-is-at-least-32-bytes-long!!")
    .build();

2. Handle the OAuth Callback

In SPA mode, your callback handler uses handle_oauth_callback_jwt_erased. This helper exchanges the OAuth code for an AccessTokenResponse containing your app's JWT.

use authkestra_actix::{handle_oauth_callback_jwt_erased, OAuthCallbackParams};

#[get("/api/callback")]
async fn callback_handler(
    data: web::Data<AppState>,
    params: web::Query<OAuthCallbackParams>,
    req: actix_web::HttpRequest,
) -> impl Responder {
    let flow = &data.authkestra.providers["github"];

    handle_oauth_callback_jwt_erased(
        flow.as_ref(),
        &req,
        params.into_inner(),
        data.authkestra.token_manager.get_manager(), // Access the configured manager
        3600,
    )
    .await
    .map_err(actix_web::error::ErrorInternalServerError)
}

Offline Validation

authkestra-actix provides a Jwt<T> extractor for offline token validation. This is useful for resource servers that need to validate tokens issued by external OIDC providers (like Google or Auth0) using their JWKS endpoint.

Configuration

You need to register Arc<JwksCache> and jsonwebtoken::Validation in your app_data.

use authkestra_token::offline_validation::JwksCache;
use jsonwebtoken::{Algorithm, Validation};

// ... other setup code ...

let jwks_uri = "https://www.googleapis.com/oauth2/v3/certs".to_string();
let jwks_cache = Arc::new(JwksCache::new(jwks_uri, Duration::from_secs(3600)).await?);

let mut validation = Validation::new(Algorithm::RS256);
validation.set_issuer(&["https://accounts.google.com"]);

App::new()
    .app_data(web::Data::new(jwks_cache.clone()))
    .app_data(web::Data::new(validation.clone()))

Usage

use authkestra_actix::Jwt;
use serde::Deserialize;

#[derive(Deserialize)]
struct MyClaims {
    sub: String,
}

#[get("/api/external")]
async fn external_api(Jwt(claims): Jwt<MyClaims>) -> impl Responder {
    HttpResponse::Ok().json(claims)
}

Conclusion

By leveraging typestates and specialized extractors, authkestra-actix provides a robust and type-safe way to handle authentication in Actix Web.

For a complete working implementation, check out the actix_credentials.rs example in our GitHub repository.

On this page